@@ -84,13 +84,67 @@ 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 parts: Vec < & str > = s. split ( ':' ) . collect ( ) ;
122+ if parts. len ( ) != 2 {
123+ return Err ( serde:: de:: Error :: custom ( format ! (
124+ "Invalid variant format: '{}'. Expected 'name:tag'" ,
125+ s
126+ ) ) ) ;
127+ }
128+ let name = VariantName :: from_str ( parts[ 0 ] ) . map_err ( |e| {
129+ serde:: de:: Error :: custom ( format ! ( "Invalid variant name: {}" , e) )
130+ } ) ?;
131+ let tag = parts[ 1 ]
132+ . parse :: < u8 > ( )
133+ . map_err ( |e| serde:: de:: Error :: custom ( format ! ( "Invalid variant tag: {}" , e) ) ) ?;
134+ Ok ( Variant { name, tag } )
135+ } else {
136+ #[ cfg_attr( feature = "serde" , derive( Deserialize ) , serde( crate = "serde_crate" ) ) ]
137+ struct VariantFields {
138+ name : VariantName ,
139+ tag : u8 ,
140+ }
141+ let VariantFields { name, tag } = VariantFields :: deserialize ( deserializer) ?;
142+ Ok ( Variant { name, tag } )
143+ }
144+ }
145+ }
146+ }
147+
94148impl Variant {
95149 pub fn named ( tag : u8 , name : VariantName ) -> Variant { Variant { name, tag } }
96150
@@ -138,3 +192,34 @@ impl Display for Variant {
138192 Ok ( ( ) )
139193 }
140194}
195+
196+ #[ cfg( test) ]
197+ mod test {
198+ #![ allow( unused) ]
199+
200+ use std:: io:: Cursor ;
201+
202+ use crate :: * ;
203+
204+ #[ cfg( feature = "serde" ) ]
205+ #[ test]
206+ fn variant_serde_roundtrip ( ) {
207+ let variant_orig = Variant :: strict_dumb ( ) ;
208+
209+ // CBOR
210+ let mut buf = Vec :: new ( ) ;
211+ ciborium:: into_writer ( & variant_orig, & mut buf) . unwrap ( ) ;
212+ let variant_post: Variant = ciborium:: from_reader ( Cursor :: new ( & buf) ) . unwrap ( ) ;
213+ assert_eq ! ( variant_orig, variant_post) ;
214+
215+ // JSON
216+ let variant_str = serde_json:: to_string ( & variant_orig) . unwrap ( ) ;
217+ let variant_post: Variant = serde_json:: from_str ( & variant_str) . unwrap ( ) ;
218+ assert_eq ! ( variant_orig, variant_post) ;
219+
220+ // YAML
221+ let variant_str = serde_yaml:: to_string ( & variant_orig) . unwrap ( ) ;
222+ let variant_post: Variant = serde_yaml:: from_str ( & variant_str) . unwrap ( ) ;
223+ assert_eq ! ( variant_orig, variant_post) ;
224+ }
225+ }
0 commit comments