@@ -84,13 +84,80 @@ impl Display for Sizing {
8484}
8585
8686#[ derive( Clone , Eq , Debug ) ]
87- #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) , serde( crate = "serde_crate" ) ) ]
8887pub struct Variant {
8988 pub name : VariantName ,
9089 pub tag : u8 ,
9190}
9291impl_strict_struct ! ( Variant , STRICT_TYPES_LIB ; name, tag) ;
9392
93+ #[ cfg( feature = "serde" ) ]
94+ mod _serde {
95+ use std:: str:: FromStr ;
96+
97+ use serde_crate:: ser:: SerializeStruct ;
98+ use serde_crate:: { Deserialize , Deserializer , Serialize , Serializer } ;
99+
100+ use super :: * ;
101+
102+ impl Serialize for Variant {
103+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
104+ where S : Serializer {
105+ if serializer. is_human_readable ( ) {
106+ serializer. serialize_str ( & format ! ( "{}:{}" , self . name, self . tag) )
107+ } else {
108+ let mut s = serializer. serialize_struct ( "Variant" , 2 ) ?;
109+ s. serialize_field ( "name" , & self . name ) ?;
110+ s. serialize_field ( "tag" , & self . tag ) ?;
111+ s. end ( )
112+ }
113+ }
114+ }
115+
116+ impl < ' de > Deserialize < ' de > for Variant {
117+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
118+ where D : Deserializer < ' de > {
119+ if deserializer. is_human_readable ( ) {
120+ let s = String :: deserialize ( deserializer) ?;
121+ let mut split = s. split ( ':' ) ;
122+ let ( name, tag) = ( split. next ( ) , split. next ( ) ) ;
123+ if split. next ( ) . is_some ( ) {
124+ return Err ( serde:: de:: Error :: custom ( format ! (
125+ "Invalid variant format: '{}'. Expected 'name:tag'" ,
126+ s
127+ ) ) ) ;
128+ }
129+ match ( name, tag) {
130+ ( Some ( name) , Some ( tag) ) => {
131+ let name = VariantName :: from_str ( name) . map_err ( |e| {
132+ serde:: de:: Error :: custom ( format ! ( "Invalid variant name: {}" , e) )
133+ } ) ?;
134+ let tag = tag. parse :: < u8 > ( ) . map_err ( |e| {
135+ serde:: de:: Error :: custom ( format ! ( "Invalid variant tag: {}" , e) )
136+ } ) ?;
137+ Ok ( Variant { name, tag } )
138+ }
139+ _ => Err ( serde:: de:: Error :: custom ( format ! (
140+ "Invalid variant format: '{}'. Expected 'name:tag'" ,
141+ s
142+ ) ) ) ,
143+ }
144+ } else {
145+ #[ cfg_attr(
146+ feature = "serde" ,
147+ derive( Deserialize ) ,
148+ serde( crate = "serde_crate" , rename = "Variant" )
149+ ) ]
150+ struct VariantFields {
151+ name : VariantName ,
152+ tag : u8 ,
153+ }
154+ let VariantFields { name, tag } = VariantFields :: deserialize ( deserializer) ?;
155+ Ok ( Variant { name, tag } )
156+ }
157+ }
158+ }
159+ }
160+
94161impl Variant {
95162 pub fn named ( tag : u8 , name : VariantName ) -> Variant { Variant { name, tag } }
96163
@@ -138,3 +205,34 @@ impl Display for Variant {
138205 Ok ( ( ) )
139206 }
140207}
208+
209+ #[ cfg( test) ]
210+ mod test {
211+ #![ allow( unused) ]
212+
213+ use std:: io:: Cursor ;
214+
215+ use crate :: * ;
216+
217+ #[ cfg( feature = "serde" ) ]
218+ #[ test]
219+ fn variant_serde_roundtrip ( ) {
220+ let variant_orig = Variant :: strict_dumb ( ) ;
221+
222+ // CBOR
223+ let mut buf = Vec :: new ( ) ;
224+ ciborium:: into_writer ( & variant_orig, & mut buf) . unwrap ( ) ;
225+ let variant_post: Variant = ciborium:: from_reader ( Cursor :: new ( & buf) ) . unwrap ( ) ;
226+ assert_eq ! ( variant_orig, variant_post) ;
227+
228+ // JSON
229+ let variant_str = serde_json:: to_string ( & variant_orig) . unwrap ( ) ;
230+ let variant_post: Variant = serde_json:: from_str ( & variant_str) . unwrap ( ) ;
231+ assert_eq ! ( variant_orig, variant_post) ;
232+
233+ // YAML
234+ let variant_str = serde_yaml:: to_string ( & variant_orig) . unwrap ( ) ;
235+ let variant_post: Variant = serde_yaml:: from_str ( & variant_str) . unwrap ( ) ;
236+ assert_eq ! ( variant_orig, variant_post) ;
237+ }
238+ }
0 commit comments