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 {
@@ -170,6 +205,30 @@ impl From<core::net::IpAddr> for IpAddress {
170205 }
171206}
172207
208+ impl From < core:: net:: Ipv4Addr > for IpAddress {
209+ fn from ( value : core:: net:: Ipv4Addr ) -> Self {
210+ Self :: new_v4 ( value. octets ( ) )
211+ }
212+ }
213+
214+ impl From < core:: net:: Ipv6Addr > for IpAddress {
215+ fn from ( value : core:: net:: Ipv6Addr ) -> Self {
216+ Self :: new_v6 ( value. octets ( ) )
217+ }
218+ }
219+
220+ impl From < [ u8 ; 4 ] > for IpAddress {
221+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
222+ Self :: new_v4 ( octets)
223+ }
224+ }
225+
226+ impl From < [ u8 ; 16 ] > for IpAddress {
227+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
228+ Self :: new_v6 ( octets)
229+ }
230+ }
231+
173232/// UEFI Media Access Control (MAC) address.
174233///
175234/// UEFI supports multiple network protocols and hardware types, not just
@@ -179,6 +238,13 @@ impl From<core::net::IpAddr> for IpAddress {
179238///
180239/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
181240/// address with the rest of the bytes being zero.
241+ ///
242+ /// # Conversions and Relation to [`core::net`]
243+ ///
244+ /// There is no matching type in [`core::net`] but the following [`From`]
245+ /// implementations exist:
246+ /// - `[u8; 6]` <-> [`MacAddress`]
247+ /// - `[u8; 32]` -> [`MacAddress`]
182248#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
183249#[ repr( transparent) ]
184250pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -200,7 +266,7 @@ impl MacAddress {
200266 }
201267}
202268
203- // Normal/typical MAC addresses, such as in Ethernet .
269+ // Normal Ethernet MAC address .
204270impl From < [ u8 ; 6 ] > for MacAddress {
205271 fn from ( octets : [ u8 ; 6 ] ) -> Self {
206272 let mut buffer = [ 0 ; 32 ] ;
@@ -209,12 +275,20 @@ impl From<[u8; 6]> for MacAddress {
209275 }
210276}
211277
278+ // Normal Ethernet MAC address.
212279impl From < MacAddress > for [ u8 ; 6 ] {
213280 fn from ( MacAddress ( o) : MacAddress ) -> Self {
214281 [ o[ 0 ] , o[ 1 ] , o[ 2 ] , o[ 3 ] , o[ 4 ] , o[ 5 ] ]
215282 }
216283}
217284
285+ // UEFI MAC addresses.
286+ impl From < [ u8 ; 32 ] > for MacAddress {
287+ fn from ( octets : [ u8 ; 32 ] ) -> Self {
288+ Self ( octets)
289+ }
290+ }
291+
218292#[ cfg( test) ]
219293mod tests {
220294 use super :: * ;
@@ -267,4 +341,66 @@ mod tests {
267341 assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
268342 assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
269343 }
344+
345+ /// Tests the From-impls from the documentation.
346+ #[ test]
347+ fn test_promised_from_impls ( ) {
348+ // octets -> Ipv4Address
349+ {
350+ let octets = [ 0_u8 , 1 , 2 , 3 ] ;
351+ assert_eq ! ( Ipv4Address :: from( octets) , Ipv4Address ( octets) ) ;
352+ let uefi_addr = IpAddress :: from ( octets) ;
353+ assert_eq ! ( & octets, & unsafe { uefi_addr. v4. octets( ) } ) ;
354+ }
355+ // octets -> Ipv6Address
356+ {
357+ let octets = [ 0_u8 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ;
358+ assert_eq ! ( Ipv6Address :: from( octets) , Ipv6Address ( octets) ) ;
359+ let uefi_addr = IpAddress :: from ( octets) ;
360+ assert_eq ! ( & octets, & unsafe { uefi_addr. v6. octets( ) } ) ;
361+ }
362+ // StdIpv4Addr -> Ipv4Address
363+ {
364+ let octets = [ 7 , 5 , 3 , 1 ] ;
365+ let core_ipv4_addr = core:: net:: Ipv4Addr :: from ( octets) ;
366+ assert_eq ! ( Ipv4Address :: from( core_ipv4_addr) . octets( ) , octets) ;
367+ assert_eq ! (
368+ unsafe { IpAddress :: from( core_ipv4_addr) . v4. octets( ) } ,
369+ octets
370+ ) ;
371+ }
372+ // StdIpv6Addr -> Ipv6Address
373+ {
374+ let octets = [ 7 , 5 , 3 , 1 , 6 , 3 , 8 , 5 , 2 , 5 , 2 , 7 , 3 , 5 , 2 , 6 ] ;
375+ let core_ipv6_addr = core:: net:: Ipv6Addr :: from ( octets) ;
376+ assert_eq ! ( Ipv6Address :: from( core_ipv6_addr) . octets( ) , octets) ;
377+ assert_eq ! (
378+ unsafe { IpAddress :: from( core_ipv6_addr) . v6. octets( ) } ,
379+ octets
380+ ) ;
381+ }
382+ // StdIpAddr -> IpAddress
383+ {
384+ let octets = [ 8 , 8 , 2 , 6 ] ;
385+ let core_ip_addr = core:: net:: IpAddr :: from ( octets) ;
386+ assert_eq ! ( unsafe { IpAddress :: from( core_ip_addr) . v4. octets( ) } , octets) ;
387+ }
388+ // octets <-> MacAddress
389+ {
390+ let octets = [ 8 , 8 , 2 , 6 , 6 , 7 ] ;
391+ let uefi_mac_addr = MacAddress :: from ( octets) ;
392+ assert_eq ! ( uefi_mac_addr. octets( ) [ 0 ..6 ] , octets) ;
393+ let octets2: [ u8 ; 6 ] = uefi_mac_addr. into ( ) ;
394+ assert_eq ! ( octets2, octets)
395+ }
396+ // octets -> MacAddress
397+ {
398+ let octets = [
399+ 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 ,
400+ 0 , 0 , 0 , 0 , 42 ,
401+ ] ;
402+ let uefi_mac_addr = MacAddress :: from ( octets) ;
403+ assert_eq ! ( uefi_mac_addr. octets( ) , octets) ;
404+ }
405+ }
270406}
0 commit comments