1111use  core:: fmt:: { self ,  Debug ,  Display ,  Formatter } ; 
1212
1313/// An IPv4 internet protocol address. 
14+ /// 
15+ /// # Conversions and Relation to [`core::net`] 
16+ /// 
17+ /// The following [`From`] implementations exist: 
18+ ///   - `[u8; 4]` -> [`Ipv4Address`] 
19+ ///   - [`core::net::Ipv4Addr`] -> [`Ipv4Address`] 
20+ ///   - [`core::net::IpAddr`] -> [`Ipv4Address`] 
1421#[ derive( Clone ,  Copy ,  Debug ,  Default ,  Eq ,  PartialEq ,  Ord ,  PartialOrd ,  Hash ) ]  
1522#[ repr( transparent) ]  
1623pub  struct  Ipv4Address ( pub  [ u8 ;  4 ] ) ; 
@@ -35,6 +42,12 @@ impl From<Ipv4Address> for core::net::Ipv4Addr {
3542    } 
3643} 
3744
45+ impl  From < [ u8 ;  4 ] >  for  Ipv4Address  { 
46+     fn  from ( octets :  [ u8 ;  4 ] )  -> Self  { 
47+         Self ( octets) 
48+     } 
49+ } 
50+ 
3851impl  Display  for  Ipv4Address  { 
3952    fn  fmt ( & self ,  f :  & mut  Formatter < ' _ > )  -> fmt:: Result  { 
4053        let  ip = core:: net:: Ipv4Addr :: from ( * self ) ; 
@@ -43,6 +56,13 @@ impl Display for Ipv4Address {
4356} 
4457
4558/// An IPv6 internet protocol address. 
59+ /// 
60+ /// # Conversions and Relation to [`core::net`] 
61+ /// 
62+ /// The following [`From`] implementations exist: 
63+ ///   - `[u8; 16]` -> [`Ipv6Address`] 
64+ ///   - [`core::net::Ipv6Addr`] -> [`Ipv6Address`] 
65+ ///   - [`core::net::IpAddr`] -> [`Ipv6Address`] 
4666#[ derive( Clone ,  Copy ,  Debug ,  Default ,  Eq ,  PartialEq ,  Ord ,  PartialOrd ,  Hash ) ]  
4767#[ repr( transparent) ]  
4868pub  struct  Ipv6Address ( pub  [ u8 ;  16 ] ) ; 
@@ -67,6 +87,12 @@ impl From<Ipv6Address> for core::net::Ipv6Addr {
6787    } 
6888} 
6989
90+ impl  From < [ u8 ;  16 ] >  for  Ipv6Address  { 
91+     fn  from ( octets :  [ u8 ;  16 ] )  -> Self  { 
92+         Self ( octets) 
93+     } 
94+ } 
95+ 
7096impl  Display  for  Ipv6Address  { 
7197    fn  fmt ( & self ,  f :  & mut  Formatter < ' _ > )  -> fmt:: Result  { 
7298        let  ip = core:: net:: Ipv6Addr :: from ( * self ) ; 
@@ -80,6 +106,15 @@ impl Display for Ipv6Address {
80106/// type is defined in the same way as edk2 for compatibility with C code. Note 
81107/// that this is an untagged union, so there's no way to tell which type of 
82108/// address an `IpAddress` value contains without additional context. 
109+ /// 
110+ /// # Conversions and Relation to [`core::net`] 
111+ /// 
112+ /// The following [`From`] implementations exist: 
113+ ///   - `[u8; 4]` -> [`IpAddress`] 
114+ ///   - `[u8; 16]` -> [`IpAddress`] 
115+ ///   - [`core::net::Ipv4Addr`] -> [`IpAddress`] 
116+ ///   - [`core::net::Ipv6Addr`] -> [`IpAddress`] 
117+ ///   - [`core::net::IpAddr`] -> [`IpAddress`] 
83118#[ derive( Clone ,  Copy ) ]  
84119#[ repr( C ) ]  
85120pub  union  IpAddress  { 
@@ -149,6 +184,30 @@ impl From<core::net::IpAddr> for IpAddress {
149184    } 
150185} 
151186
187+ impl  From < core:: net:: Ipv4Addr >  for  IpAddress  { 
188+     fn  from ( value :  core:: net:: Ipv4Addr )  -> Self  { 
189+         Self :: new_v4 ( value. octets ( ) ) 
190+     } 
191+ } 
192+ 
193+ impl  From < core:: net:: Ipv6Addr >  for  IpAddress  { 
194+     fn  from ( value :  core:: net:: Ipv6Addr )  -> Self  { 
195+         Self :: new_v6 ( value. octets ( ) ) 
196+     } 
197+ } 
198+ 
199+ impl  From < [ u8 ;  4 ] >  for  IpAddress  { 
200+     fn  from ( octets :  [ u8 ;  4 ] )  -> Self  { 
201+         Self :: new_v4 ( octets) 
202+     } 
203+ } 
204+ 
205+ impl  From < [ u8 ;  16 ] >  for  IpAddress  { 
206+     fn  from ( octets :  [ u8 ;  16 ] )  -> Self  { 
207+         Self :: new_v6 ( octets) 
208+     } 
209+ } 
210+ 
152211/// UEFI Media Access Control (MAC) address. 
153212/// 
154213/// UEFI supports multiple network protocols and hardware types, not just 
@@ -158,6 +217,13 @@ impl From<core::net::IpAddr> for IpAddress {
158217/// 
159218/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC 
160219/// address with the rest of the bytes being zero. 
220+ /// 
221+ /// # Conversions and Relation to [`core::net`] 
222+ /// 
223+ /// There is no matching type in [`core::net`] but the following [`From`] 
224+ /// implementations exist: 
225+ ///   - `[u8; 6]` -> [`MacAddress`] 
226+ ///   - `[u8; 32]` -> [`MacAddress`] 
161227#[ derive( Clone ,  Copy ,  Debug ,  Default ,  Eq ,  PartialEq ,  Ord ,  PartialOrd ,  Hash ) ]  
162228#[ repr( transparent) ]  
163229pub  struct  MacAddress ( pub  [ u8 ;  32 ] ) ; 
@@ -185,6 +251,13 @@ impl From<MacAddress> for [u8; 6] {
185251    } 
186252} 
187253
254+ // UEFI MAC addresses. 
255+ impl  From < [ u8 ;  32 ] >  for  MacAddress  { 
256+     fn  from ( octets :  [ u8 ;  32 ] )  -> Self  { 
257+         Self ( octets) 
258+     } 
259+ } 
260+ 
188261#[ cfg( test) ]  
189262mod  tests { 
190263    use  super :: * ; 
@@ -237,4 +310,64 @@ mod tests {
237310        assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) ,  1 ) ; 
238311        assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) ,  16 ) ; 
239312    } 
313+ 
314+     /// Tests the From-impls from the documentation. 
315+ #[ test]  
316+     fn  test_promised_from_impls ( )  { 
317+         // octets -> Ipv4Address 
318+         { 
319+             let  octets = [ 0_u8 ,  1 ,  2 ,  3 ] ; 
320+             assert_eq ! ( Ipv4Address :: from( octets) ,  Ipv4Address ( octets) ) ; 
321+             let  uefi_addr = IpAddress :: from ( octets) ; 
322+             assert_eq ! ( & octets,  & unsafe  {  uefi_addr. v4. octets( )  } ) ; 
323+         } 
324+         // octets -> Ipv6Address 
325+         { 
326+             let  octets = [ 0_u8 ,  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,  10 ,  11 ,  12 ,  13 ,  14 ,  15 ] ; 
327+             assert_eq ! ( Ipv6Address :: from( octets) ,  Ipv6Address ( octets) ) ; 
328+             let  uefi_addr = IpAddress :: from ( octets) ; 
329+             assert_eq ! ( & octets,  & unsafe  {  uefi_addr. v6. octets( )  } ) ; 
330+         } 
331+         // StdIpv4Addr -> Ipv4Address 
332+         { 
333+             let  octets = [ 7 ,  5 ,  3 ,  1 ] ; 
334+             let  core_ipv4_addr = core:: net:: Ipv4Addr :: from ( octets) ; 
335+             assert_eq ! ( Ipv4Address :: from( core_ipv4_addr) . octets( ) ,  octets) ; 
336+             assert_eq ! ( 
337+                 unsafe  {  IpAddress :: from( core_ipv4_addr) . v4. octets( )  } , 
338+                 octets
339+             ) ; 
340+         } 
341+         // StdIpv6Addr -> Ipv6Address 
342+         { 
343+             let  octets = [ 7 ,  5 ,  3 ,  1 ,  6 ,  3 ,  8 ,  5 ,  2 ,  5 ,  2 ,  7 ,  3 ,  5 ,  2 ,  6 ] ; 
344+             let  core_ipv6_addr = core:: net:: Ipv6Addr :: from ( octets) ; 
345+             assert_eq ! ( Ipv6Address :: from( core_ipv6_addr) . octets( ) ,  octets) ; 
346+             assert_eq ! ( 
347+                 unsafe  {  IpAddress :: from( core_ipv6_addr) . v6. octets( )  } , 
348+                 octets
349+             ) ; 
350+         } 
351+         // StdIpAddr -> IpAddress 
352+         { 
353+             let  octets = [ 8 ,  8 ,  2 ,  6 ] ; 
354+             let  core_ip_addr = core:: net:: IpAddr :: from ( octets) ; 
355+             assert_eq ! ( unsafe  {  IpAddress :: from( core_ip_addr) . v4. octets( )  } ,  octets) ; 
356+         } 
357+         // octets -> MacAddress 
358+         { 
359+             let  octets = [ 8 ,  8 ,  2 ,  6 ,  6 ,  7 ] ; 
360+             let  uefi_mac_addr = MacAddress :: from ( octets) ; 
361+             assert_eq ! ( uefi_mac_addr. octets( ) [ 0 ..6 ] ,  octets) ; 
362+         } 
363+         // octets -> MacAddress 
364+         { 
365+             let  octets = [ 
366+                 8_u8 ,  8 ,  2 ,  6 ,  6 ,  7 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  5 ,  7 ,  0 ,  0 ,  0 , 
367+                 0 ,  0 ,  0 ,  0 ,  42 , 
368+             ] ; 
369+             let  uefi_mac_addr = MacAddress :: from ( octets) ; 
370+             assert_eq ! ( uefi_mac_addr. octets( ) ,  octets) ; 
371+         } 
372+     } 
240373} 
0 commit comments