@@ -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) ]
@@ -1530,3 +1560,104 @@ mod tests {
15301560 assert_eq ! ( format!( "{:x?}" , val) , "U16(a)" ) ;
15311561 }
15321562}
1563+
1564+ #[ cfg( all( test, feature = "serde" ) ) ]
1565+ mod serialization_tests {
1566+ use core:: fmt:: Debug ;
1567+
1568+ use serde:: { Deserialize , Serialize } ;
1569+
1570+ use crate :: {
1571+ byteorder:: { Isize , Usize , F32 , F64 , I128 , I16 , I32 , I64 , U128 , U16 , U32 , U64 } ,
1572+ BigEndian , LittleEndian ,
1573+ } ;
1574+
1575+ fn assert_roundtrip < PrimitiveType , WrapperType > (
1576+ to_serialize : WrapperType ,
1577+ primitive_value : Option < PrimitiveType > ,
1578+ ) where
1579+ WrapperType : Serialize + for < ' de > Deserialize < ' de > + PartialEq + Debug ,
1580+ PrimitiveType : Serialize + for < ' de > Deserialize < ' de > + PartialEq + Debug ,
1581+ {
1582+ let serialized_value =
1583+ serde_json:: to_string ( & to_serialize) . expect ( "Serialization to json should succeed" ) ;
1584+ let deserialized_wrapper = serde_json:: from_str ( & serialized_value)
1585+ . expect ( "Deserialization from json to wrapper type should succeed" ) ;
1586+ assert_eq ! ( to_serialize, deserialized_wrapper) ;
1587+
1588+ if let Some ( primitive_value) = primitive_value {
1589+ let deserialized_primitive = serde_json:: from_str ( & serialized_value)
1590+ . expect ( "Deserialization from json to primitive type should succeed" ) ;
1591+ assert_eq ! ( primitive_value, deserialized_primitive) ;
1592+ }
1593+ }
1594+
1595+ macro_rules! assert_serialization_roundtrip {
1596+ ( $prim: ty, $wrapper: ident, $value: expr) => { {
1597+ let primitive_value: $prim = $value;
1598+ assert_roundtrip( $wrapper:: <BigEndian >:: new( primitive_value) , Some ( primitive_value) ) ;
1599+ assert_roundtrip( $wrapper:: <LittleEndian >:: new( primitive_value) , Some ( primitive_value) ) ;
1600+ } } ;
1601+ }
1602+
1603+ #[ test]
1604+ fn serialize_native_primitives ( ) {
1605+ assert_serialization_roundtrip ! ( u16 , U16 , 0xABCDu16 ) ;
1606+ assert_serialization_roundtrip ! ( i16 , I16 , -123i16 ) ;
1607+ assert_serialization_roundtrip ! ( u32 , U32 , 0x89AB_CDEFu32 ) ;
1608+ assert_serialization_roundtrip ! ( i32 , I32 , -0x1234_5678i32 ) ;
1609+ assert_serialization_roundtrip ! ( u64 , U64 , 0x0123_4567_89AB_CDEFu64 ) ;
1610+ assert_serialization_roundtrip ! ( i64 , I64 , -0x0123_4567_89AB_CDEFi64 ) ;
1611+ assert_serialization_roundtrip ! ( u128 , U128 , 0x1234u128 ) ;
1612+ assert_serialization_roundtrip ! ( i128 , I128 , -0x1234i128 ) ;
1613+ assert_serialization_roundtrip ! ( usize , Usize , 0xBEEFusize ) ;
1614+ assert_serialization_roundtrip ! ( isize , Isize , -12isize ) ;
1615+ assert_serialization_roundtrip ! ( f32 , F32 , 1.25f32 ) ;
1616+ assert_serialization_roundtrip ! ( f64 , F64 , -0.75f64 ) ;
1617+ }
1618+
1619+ #[ derive( Serialize , Deserialize , PartialEq , Debug ) ]
1620+ struct SerializableStruct < WrapperTypeA , WrapperTypeB >
1621+ where
1622+ WrapperTypeA : PartialEq + Debug ,
1623+ WrapperTypeB : PartialEq + Debug ,
1624+ {
1625+ value_a : WrapperTypeA ,
1626+ value_b : [ WrapperTypeB ; 2 ] ,
1627+ value_c : ( WrapperTypeA , WrapperTypeB ) ,
1628+ }
1629+
1630+ macro_rules! assert_struct_serialization_roundtrip {
1631+ ( $prim: ty, $wrapper: ident, $value: expr) => { {
1632+ let primitive_value: $prim = $value;
1633+ let test_struct = SerializableStruct {
1634+ value_a: $wrapper:: <BigEndian >:: new( primitive_value) ,
1635+ value_b: [
1636+ $wrapper:: <LittleEndian >:: new( primitive_value) ,
1637+ $wrapper:: <LittleEndian >:: new( primitive_value) ,
1638+ ] ,
1639+ value_c: (
1640+ $wrapper:: <BigEndian >:: new( primitive_value) ,
1641+ $wrapper:: <LittleEndian >:: new( primitive_value) ,
1642+ ) ,
1643+ } ;
1644+ assert_roundtrip( test_struct, None :: <$prim>) ;
1645+ } } ;
1646+ }
1647+
1648+ #[ test]
1649+ fn serialize_struct ( ) {
1650+ assert_struct_serialization_roundtrip ! ( u16 , U16 , 0xABCDu16 ) ;
1651+ assert_struct_serialization_roundtrip ! ( i16 , I16 , -123i16 ) ;
1652+ assert_struct_serialization_roundtrip ! ( u32 , U32 , 0x89AB_CDEFu32 ) ;
1653+ assert_struct_serialization_roundtrip ! ( i32 , I32 , -0x1234_5678i32 ) ;
1654+ assert_struct_serialization_roundtrip ! ( u64 , U64 , 0x0123_4567_89AB_CDEFu64 ) ;
1655+ assert_struct_serialization_roundtrip ! ( i64 , I64 , -0x0123_4567_89AB_CDEFi64 ) ;
1656+ assert_struct_serialization_roundtrip ! ( u128 , U128 , 0x1234u128 ) ;
1657+ assert_struct_serialization_roundtrip ! ( i128 , I128 , -0x1234i128 ) ;
1658+ assert_struct_serialization_roundtrip ! ( usize , Usize , 0xBEEFusize ) ;
1659+ assert_struct_serialization_roundtrip ! ( isize , Isize , -12isize ) ;
1660+ assert_struct_serialization_roundtrip ! ( f32 , F32 , 1.25f32 ) ;
1661+ assert_struct_serialization_roundtrip ! ( f64 , F64 , -0.75f64 ) ;
1662+ }
1663+ }
0 commit comments