@@ -1835,9 +1835,8 @@ pub struct FlagsMap<'a> {
18351835/// - `Deref`/`DerefMut` for direct byte manipulation
18361836/// - `From` for construction from byte arrays
18371837/// - `TryFrom` for fallible construction from slices
1838- #[ derive( Debug , Serialize , Deserialize , PartialEq , Eq , PartialOrd , Ord , Clone ) ]
1838+ #[ derive( Debug , PartialEq , Eq , PartialOrd , Ord , Clone ) ]
18391839#[ repr( C ) ]
1840- #[ serde( untagged) ]
18411840pub enum MacAddrTypeChoice {
18421841 /// 48-bit EUI address
18431842 Eui48Addr ( Eui48AddrType ) ,
@@ -1885,6 +1884,24 @@ impl TryFrom<&[u8]> for MacAddrTypeChoice {
18851884 }
18861885}
18871886
1887+ impl TryFrom < & str > for MacAddrTypeChoice {
1888+ type Error = TriplesError ;
1889+
1890+ fn try_from ( value : & str ) -> std:: result:: Result < Self , Self :: Error > {
1891+ let parts: Vec < u8 > = value
1892+ . split ( "-" )
1893+ . map ( |x| u8:: from_str_radix ( x, 16 ) . map_err ( |_| TriplesError :: InvalidMacAddrType ) )
1894+ . collect :: < std:: result:: Result < Vec < u8 > , TriplesError > > ( ) ?;
1895+
1896+ let n = parts. len ( ) ;
1897+ match n {
1898+ 6 => Ok ( Self :: Eui48Addr ( parts. try_into ( ) . unwrap ( ) ) ) ,
1899+ 8 => Ok ( Self :: Eui64Addr ( parts. try_into ( ) . unwrap ( ) ) ) ,
1900+ _ => Err ( TriplesError :: InvalidMacAddrType ) ,
1901+ }
1902+ }
1903+ }
1904+
18881905impl AsRef < [ u8 ] > for MacAddrTypeChoice {
18891906 fn as_ref ( & self ) -> & [ u8 ] {
18901907 match self {
@@ -1923,6 +1940,62 @@ impl DerefMut for MacAddrTypeChoice {
19231940 }
19241941}
19251942
1943+ impl Display for MacAddrTypeChoice {
1944+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
1945+ match self {
1946+ Self :: Eui48Addr ( addr) => write ! (
1947+ f,
1948+ "{:02X?}-{:02X?}-{:02X?}-{:02X?}-{:02X?}-{:02X?}" ,
1949+ addr[ 0 ] , addr[ 1 ] , addr[ 2 ] , addr[ 3 ] , addr[ 4 ] , addr[ 5 ]
1950+ ) ,
1951+ Self :: Eui64Addr ( addr) => write ! (
1952+ f,
1953+ "{:02X?}-{:02X?}-{:02X?}-{:02X?}-{:02X?}-{:02X?}-{:02X?}-{:02X?}" ,
1954+ addr[ 0 ] , addr[ 1 ] , addr[ 2 ] , addr[ 3 ] , addr[ 4 ] , addr[ 5 ] , addr[ 6 ] , addr[ 7 ]
1955+ ) ,
1956+ }
1957+ }
1958+ }
1959+
1960+ impl Serialize for MacAddrTypeChoice {
1961+ fn serialize < S > ( & self , serializer : S ) -> std:: result:: Result < S :: Ok , S :: Error >
1962+ where
1963+ S : Serializer ,
1964+ {
1965+ let is_human_readable = serializer. is_human_readable ( ) ;
1966+
1967+ if is_human_readable {
1968+ self . to_string ( ) . serialize ( serializer)
1969+ } else {
1970+ match self {
1971+ Self :: Eui48Addr ( octets) => serializer. serialize_bytes ( octets. as_slice ( ) ) ,
1972+ Self :: Eui64Addr ( octets) => serializer. serialize_bytes ( octets. as_slice ( ) ) ,
1973+ }
1974+ }
1975+ }
1976+ }
1977+
1978+ impl < ' de > Deserialize < ' de > for MacAddrTypeChoice {
1979+ fn deserialize < D > ( deserializer : D ) -> std:: result:: Result < Self , D :: Error >
1980+ where
1981+ D : Deserializer < ' de > ,
1982+ {
1983+ let is_human_readable = deserializer. is_human_readable ( ) ;
1984+
1985+ if is_human_readable {
1986+ String :: deserialize ( deserializer) ?
1987+ . as_str ( )
1988+ . try_into ( )
1989+ . map_err ( de:: Error :: custom)
1990+ } else {
1991+ Vec :: < u8 > :: deserialize ( deserializer) ?
1992+ . as_slice ( )
1993+ . try_into ( )
1994+ . map_err ( de:: Error :: custom)
1995+ }
1996+ }
1997+ }
1998+
19261999/// 48-bit MAC address type
19272000pub type Eui48AddrType = [ u8 ; 6 ] ;
19282001/// 64-bit MAC address type
@@ -3562,4 +3635,55 @@ mod test {
35623635
35633636 assert_eq ! ( addr_de, addr) ;
35643637 }
3638+
3639+ #[ test]
3640+ fn test_mac_addr_serde ( ) {
3641+ let addr = MacAddrTypeChoice :: Eui48Addr ( [ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 ] ) ;
3642+
3643+ let json = serde_json:: to_string ( & addr) . unwrap ( ) ;
3644+
3645+ assert_eq ! ( "\" 01-02-03-04-05-06\" " , json) ;
3646+
3647+ let addr_de: MacAddrTypeChoice = serde_json:: from_str ( & json) . unwrap ( ) ;
3648+
3649+ assert_eq ! ( addr_de, addr) ;
3650+
3651+ let mut actual: Vec < u8 > = vec ! [ ] ;
3652+ ciborium:: into_writer ( & addr, & mut actual) . unwrap ( ) ;
3653+
3654+ let expected = vec ! [
3655+ 0x46 , // bstr(6),
3656+ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 ,
3657+ ] ;
3658+
3659+ assert_eq ! ( actual, expected) ;
3660+
3661+ let addr_de: MacAddrTypeChoice = ciborium:: from_reader ( expected. as_slice ( ) ) . unwrap ( ) ;
3662+
3663+ assert_eq ! ( addr_de, addr) ;
3664+
3665+ let addr = MacAddrTypeChoice :: Eui64Addr ( [ 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F , 0x10 , 0x20 ] ) ;
3666+
3667+ let json = serde_json:: to_string ( & addr) . unwrap ( ) ;
3668+
3669+ assert_eq ! ( "\" 0A-0B-0C-0D-0E-0F-10-20\" " , json) ;
3670+
3671+ let addr_de: MacAddrTypeChoice = serde_json:: from_str ( & json) . unwrap ( ) ;
3672+
3673+ assert_eq ! ( addr_de, addr) ;
3674+
3675+ let mut actual: Vec < u8 > = vec ! [ ] ;
3676+ ciborium:: into_writer ( & addr, & mut actual) . unwrap ( ) ;
3677+
3678+ let expected = vec ! [
3679+ 0x48 , // bstr(8),
3680+ 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f , 0x10 , 0x20 ,
3681+ ] ;
3682+
3683+ assert_eq ! ( actual, expected) ;
3684+
3685+ let addr_de: MacAddrTypeChoice = ciborium:: from_reader ( expected. as_slice ( ) ) . unwrap ( ) ;
3686+
3687+ assert_eq ! ( addr_de, addr) ;
3688+ }
35653689}
0 commit comments