@@ -23,6 +23,7 @@ use std::cmp::Ordering;
2323use std:: fmt:: { self , Display , Formatter } ;
2424use std:: hash:: { Hash , Hasher } ;
2525use std:: io;
26+ use std:: str:: FromStr ;
2627
2728use crate :: { ReadStruct , VariantName , WriteStruct , STRICT_TYPES_LIB } ;
2829
@@ -84,13 +85,43 @@ impl Display for Sizing {
8485}
8586
8687#[ derive( Clone , Eq , Debug ) ]
87- #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) , serde( crate = "serde_crate" ) ) ]
8888pub struct Variant {
8989 pub name : VariantName ,
9090 pub tag : u8 ,
9191}
9292impl_strict_struct ! ( Variant , STRICT_TYPES_LIB ; name, tag) ;
9393
94+ #[ cfg( feature = "serde" ) ]
95+ mod _serde {
96+ use serde_crate:: { Deserialize , Deserializer , Serialize , Serializer } ;
97+
98+ use super :: * ;
99+
100+ impl Serialize for Variant {
101+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
102+ where S : Serializer {
103+ if serializer. is_human_readable ( ) {
104+ serializer. serialize_str ( & self . to_string ( ) )
105+ } else {
106+ ( & self . name , self . tag ) . serialize ( serializer)
107+ }
108+ }
109+ }
110+
111+ impl < ' de > Deserialize < ' de > for Variant {
112+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
113+ where D : Deserializer < ' de > {
114+ if deserializer. is_human_readable ( ) {
115+ let s = String :: deserialize ( deserializer) ?;
116+ Variant :: from_str ( & s) . map_err ( serde:: de:: Error :: custom)
117+ } else {
118+ let ( name, tag) : ( VariantName , u8 ) = Deserialize :: deserialize ( deserializer) ?;
119+ Ok ( Variant { name, tag } )
120+ }
121+ }
122+ }
123+ }
124+
94125impl Variant {
95126 pub fn named ( tag : u8 , name : VariantName ) -> Variant { Variant { name, tag } }
96127
@@ -134,7 +165,22 @@ impl Ord for Variant {
134165
135166impl Display for Variant {
136167 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
137- write ! ( f, "{}" , self . name) ?;
168+ write ! ( f, "{}:{} " , self . name, self . tag ) ?;
138169 Ok ( ( ) )
139170 }
140171}
172+
173+ impl FromStr for Variant {
174+ type Err = String ;
175+
176+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
177+ let parts: Vec < & str > = s. split ( ':' ) . collect ( ) ;
178+ if parts. len ( ) != 2 {
179+ return Err ( format ! ( "Invalid variant format: '{}'. Expected 'name:tag'" , s) ) ;
180+ }
181+ let name =
182+ VariantName :: from_str ( parts[ 0 ] ) . map_err ( |e| format ! ( "Invalid variant name: {}" , e) ) ?;
183+ let tag = parts[ 1 ] . parse :: < u8 > ( ) . map_err ( |e| format ! ( "Invalid variant tag: {}" , e) ) ?;
184+ Ok ( Variant { name, tag } )
185+ }
186+ }
0 commit comments