@@ -613,6 +613,36 @@ example of how it can be used for parsing UDP packets.
613613 }
614614 }
615615
616+ #[ cfg_attr( doc_cfg, doc( cfg( feature = "serde" ) ) ) ]
617+ #[ cfg( feature = "serde" ) ]
618+ impl <O : ByteOrder > serde:: Serialize for $name<O >
619+ where
620+ $native: serde:: Serialize ,
621+ {
622+ #[ inline( always) ]
623+ fn serialize<S >( & self , serializer: S ) -> Result <S :: Ok , S :: Error >
624+ where
625+ S : serde:: Serializer ,
626+ {
627+ $native:: serialize( & self . get( ) , serializer)
628+ }
629+ }
630+
631+ #[ cfg_attr( doc_cfg, doc( cfg( feature = "serde" ) ) ) ]
632+ #[ cfg( feature = "serde" ) ]
633+ impl <' de, O : ByteOrder > serde:: Deserialize <' de> for $name<O >
634+ where
635+ $native: serde:: Deserialize <' de>,
636+ {
637+ #[ inline( always) ]
638+ fn deserialize<D >( deserializer: D ) -> Result <Self , D :: Error >
639+ where
640+ D : serde:: Deserializer <' de>,
641+ {
642+ $native:: deserialize( deserializer) . map( Self :: from)
643+ }
644+ }
645+
616646 $(
617647 impl <O : ByteOrder > From <$name<O >> for $larger_native {
618648 #[ inline( always) ]
@@ -1562,3 +1592,104 @@ mod tests {
15621592 assert_eq ! ( val_be_i16. cmp( & val_be_i16) , core:: cmp:: Ordering :: Equal ) ;
15631593 }
15641594}
1595+
1596+ #[ cfg( all( test, feature = "serde" ) ) ]
1597+ mod serialization_tests {
1598+ use core:: fmt:: Debug ;
1599+
1600+ use serde:: { Deserialize , Serialize } ;
1601+
1602+ use crate :: {
1603+ byteorder:: { Isize , Usize , F32 , F64 , I128 , I16 , I32 , I64 , U128 , U16 , U32 , U64 } ,
1604+ BigEndian , LittleEndian ,
1605+ } ;
1606+
1607+ fn assert_roundtrip < PrimitiveType , WrapperType > (
1608+ to_serialize : WrapperType ,
1609+ primitive_value : Option < PrimitiveType > ,
1610+ ) where
1611+ WrapperType : Serialize + for < ' de > Deserialize < ' de > + PartialEq + Debug ,
1612+ PrimitiveType : Serialize + for < ' de > Deserialize < ' de > + PartialEq + Debug ,
1613+ {
1614+ let serialized_value =
1615+ serde_json:: to_string ( & to_serialize) . expect ( "Serialization to json should succeed" ) ;
1616+ let deserialized_wrapper = serde_json:: from_str ( & serialized_value)
1617+ . expect ( "Deserialization from json to wrapper type should succeed" ) ;
1618+ assert_eq ! ( to_serialize, deserialized_wrapper) ;
1619+
1620+ if let Some ( primitive_value) = primitive_value {
1621+ let deserialized_primitive = serde_json:: from_str ( & serialized_value)
1622+ . expect ( "Deserialization from json to primitive type should succeed" ) ;
1623+ assert_eq ! ( primitive_value, deserialized_primitive) ;
1624+ }
1625+ }
1626+
1627+ macro_rules! assert_serialization_roundtrip {
1628+ ( $prim: ty, $wrapper: ident, $value: expr) => { {
1629+ let primitive_value: $prim = $value;
1630+ assert_roundtrip( $wrapper:: <BigEndian >:: new( primitive_value) , Some ( primitive_value) ) ;
1631+ assert_roundtrip( $wrapper:: <LittleEndian >:: new( primitive_value) , Some ( primitive_value) ) ;
1632+ } } ;
1633+ }
1634+
1635+ #[ test]
1636+ fn serialize_native_primitives ( ) {
1637+ assert_serialization_roundtrip ! ( u16 , U16 , 0xABCDu16 ) ;
1638+ assert_serialization_roundtrip ! ( i16 , I16 , -123i16 ) ;
1639+ assert_serialization_roundtrip ! ( u32 , U32 , 0x89AB_CDEFu32 ) ;
1640+ assert_serialization_roundtrip ! ( i32 , I32 , -0x1234_5678i32 ) ;
1641+ assert_serialization_roundtrip ! ( u64 , U64 , 0x0123_4567_89AB_CDEFu64 ) ;
1642+ assert_serialization_roundtrip ! ( i64 , I64 , -0x0123_4567_89AB_CDEFi64 ) ;
1643+ assert_serialization_roundtrip ! ( u128 , U128 , 0x1234u128 ) ;
1644+ assert_serialization_roundtrip ! ( i128 , I128 , -0x1234i128 ) ;
1645+ assert_serialization_roundtrip ! ( usize , Usize , 0xBEEFusize ) ;
1646+ assert_serialization_roundtrip ! ( isize , Isize , -12isize ) ;
1647+ assert_serialization_roundtrip ! ( f32 , F32 , 1.25f32 ) ;
1648+ assert_serialization_roundtrip ! ( f64 , F64 , -0.75f64 ) ;
1649+ }
1650+
1651+ #[ derive( Serialize , Deserialize , PartialEq , Debug ) ]
1652+ struct SerializableStruct < WrapperTypeA , WrapperTypeB >
1653+ where
1654+ WrapperTypeA : PartialEq + Debug ,
1655+ WrapperTypeB : PartialEq + Debug ,
1656+ {
1657+ value_a : WrapperTypeA ,
1658+ value_b : [ WrapperTypeB ; 2 ] ,
1659+ value_c : ( WrapperTypeA , WrapperTypeB ) ,
1660+ }
1661+
1662+ macro_rules! assert_struct_serialization_roundtrip {
1663+ ( $prim: ty, $wrapper: ident, $value: expr) => { {
1664+ let primitive_value: $prim = $value;
1665+ let test_struct = SerializableStruct {
1666+ value_a: $wrapper:: <BigEndian >:: new( primitive_value) ,
1667+ value_b: [
1668+ $wrapper:: <LittleEndian >:: new( primitive_value) ,
1669+ $wrapper:: <LittleEndian >:: new( primitive_value) ,
1670+ ] ,
1671+ value_c: (
1672+ $wrapper:: <BigEndian >:: new( primitive_value) ,
1673+ $wrapper:: <LittleEndian >:: new( primitive_value) ,
1674+ ) ,
1675+ } ;
1676+ assert_roundtrip( test_struct, None :: <$prim>) ;
1677+ } } ;
1678+ }
1679+
1680+ #[ test]
1681+ fn serialize_struct ( ) {
1682+ assert_struct_serialization_roundtrip ! ( u16 , U16 , 0xABCDu16 ) ;
1683+ assert_struct_serialization_roundtrip ! ( i16 , I16 , -123i16 ) ;
1684+ assert_struct_serialization_roundtrip ! ( u32 , U32 , 0x89AB_CDEFu32 ) ;
1685+ assert_struct_serialization_roundtrip ! ( i32 , I32 , -0x1234_5678i32 ) ;
1686+ assert_struct_serialization_roundtrip ! ( u64 , U64 , 0x0123_4567_89AB_CDEFu64 ) ;
1687+ assert_struct_serialization_roundtrip ! ( i64 , I64 , -0x0123_4567_89AB_CDEFi64 ) ;
1688+ assert_struct_serialization_roundtrip ! ( u128 , U128 , 0x1234u128 ) ;
1689+ assert_struct_serialization_roundtrip ! ( i128 , I128 , -0x1234i128 ) ;
1690+ assert_struct_serialization_roundtrip ! ( usize , Usize , 0xBEEFusize ) ;
1691+ assert_struct_serialization_roundtrip ! ( isize , Isize , -12isize ) ;
1692+ assert_struct_serialization_roundtrip ! ( f32 , F32 , 1.25f32 ) ;
1693+ assert_struct_serialization_roundtrip ! ( f64 , F64 , -0.75f64 ) ;
1694+ }
1695+ }
0 commit comments