@@ -13,6 +13,13 @@ use core::mem;
1313use core:: net:: { IpAddr as StdIpAddr , Ipv4Addr as StdIpv4Addr , Ipv6Addr as StdIpv6Addr } ;
1414
1515/// An IPv4 internet protocol address.
16+ ///
17+ /// # Conversions and Relation to [`core::net`]
18+ ///
19+ /// The following [`From`] implementations exist:
20+ /// - `[u8; 4]` -> [`Ipv4Address`]
21+ /// - [`core::net::Ipv4Addr`] -> [`Ipv4Address`]
22+ /// - [`core::net::IpAddr`] -> [`Ipv4Address`]
1623#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
1724#[ repr( transparent) ]
1825pub struct Ipv4Address ( pub [ u8 ; 4 ] ) ;
@@ -37,7 +44,20 @@ impl From<Ipv4Address> for StdIpv4Addr {
3744 }
3845}
3946
47+ impl From < [ u8 ; 4 ] > for Ipv4Address {
48+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
49+ Self ( octets)
50+ }
51+ }
52+
4053/// An IPv6 internet protocol address.
54+ ///
55+ /// # Conversions and Relation to [`core::net`]
56+ ///
57+ /// The following [`From`] implementations exist:
58+ /// - `[u8; 16]` -> [`Ipv6Address`]
59+ /// - [`core::net::Ipv6Addr`] -> [`Ipv6Address`]
60+ /// - [`core::net::IpAddr`] -> [`Ipv6Address`]
4161#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
4262#[ repr( transparent) ]
4363pub struct Ipv6Address ( pub [ u8 ; 16 ] ) ;
@@ -62,12 +82,27 @@ impl From<Ipv6Address> for StdIpv6Addr {
6282 }
6383}
6484
65- /// An IPv4 or IPv6 internet protocol address that is ABI compatible with EFI.
85+ impl From < [ u8 ; 16 ] > for Ipv6Address {
86+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
87+ Self ( octets)
88+ }
89+ }
90+
91+ /// EFI ABI-compatible union of an IPv4 or IPv6 internet protocol address.
6692///
6793/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
6894/// type is defined in the same way as edk2 for compatibility with C code. Note
6995/// that this is an untagged union, so there's no way to tell which type of
7096/// address an `IpAddress` value contains without additional context.
97+ ///
98+ /// # Conversions and Relation to [`core::net`]
99+ ///
100+ /// The following [`From`] implementations exist:
101+ /// - `[u8; 4]` -> [`IpAddress`]
102+ /// - `[u8; 16]` -> [`IpAddress`]
103+ /// - [`core::net::Ipv4Addr`] -> [`IpAddress`]
104+ /// - [`core::net::Ipv6Addr`] -> [`IpAddress`]
105+ /// - [`core::net::IpAddr`] -> [`IpAddress`]
71106#[ derive( Clone , Copy ) ]
72107#[ repr( C ) ]
73108pub union IpAddress {
@@ -152,6 +187,30 @@ impl From<StdIpAddr> for IpAddress {
152187 }
153188}
154189
190+ impl From < StdIpv4Addr > for IpAddress {
191+ fn from ( value : StdIpv4Addr ) -> Self {
192+ Self :: new_v4 ( value. octets ( ) )
193+ }
194+ }
195+
196+ impl From < StdIpv6Addr > for IpAddress {
197+ fn from ( value : StdIpv6Addr ) -> Self {
198+ Self :: new_v6 ( value. octets ( ) )
199+ }
200+ }
201+
202+ impl From < [ u8 ; 4 ] > for IpAddress {
203+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
204+ Self :: new_v4 ( octets)
205+ }
206+ }
207+
208+ impl From < [ u8 ; 16 ] > for IpAddress {
209+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
210+ Self :: new_v6 ( octets)
211+ }
212+ }
213+
155214/// UEFI Media Access Control (MAC) address.
156215///
157216/// UEFI supports multiple network protocols and hardware types, not just
@@ -161,6 +220,13 @@ impl From<StdIpAddr> for IpAddress {
161220///
162221/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
163222/// address with the rest of the bytes being zero.
223+ ///
224+ /// # Conversions and Relation to [`core::net`]
225+ ///
226+ /// There is no matching type in [`core::net`] but the following [`From`]
227+ /// implementations exist:
228+ /// - `[u8; 6]` -> [`MacAddress`]
229+ /// - `[u8; 32]` -> [`MacAddress`]
164230#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
165231#[ repr( transparent) ]
166232pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -182,9 +248,10 @@ impl From<[u8; 6]> for MacAddress {
182248 }
183249}
184250
185- impl From < MacAddress > for [ u8 ; 6 ] {
186- fn from ( MacAddress ( o) : MacAddress ) -> Self {
187- [ o[ 0 ] , o[ 1 ] , o[ 2 ] , o[ 3 ] , o[ 4 ] , o[ 5 ] ]
251+ // UEFI MAC addresses.
252+ impl From < [ u8 ; 32 ] > for MacAddress {
253+ fn from ( octets : [ u8 ; 32 ] ) -> Self {
254+ Self ( octets)
188255 }
189256}
190257
@@ -240,4 +307,64 @@ mod tests {
240307 assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
241308 assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
242309 }
310+
311+ /// Tests the From-impls from the documentation.
312+ #[ test]
313+ fn test_promised_from_impls ( ) {
314+ // octets -> Ipv4Address
315+ {
316+ let octets = [ 0_u8 , 1 , 2 , 3 ] ;
317+ assert_eq ! ( Ipv4Address :: from( octets) , Ipv4Address ( octets) ) ;
318+ let uefi_addr = IpAddress :: from ( octets) ;
319+ assert_eq ! ( & octets, & unsafe { uefi_addr. v4. octets( ) } ) ;
320+ }
321+ // octets -> Ipv6Address
322+ {
323+ let octets = [ 0_u8 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ;
324+ assert_eq ! ( Ipv6Address :: from( octets) , Ipv6Address ( octets) ) ;
325+ let uefi_addr = IpAddress :: from ( octets) ;
326+ assert_eq ! ( & octets, & unsafe { uefi_addr. v6. octets( ) } ) ;
327+ }
328+ // StdIpv4Addr -> Ipv4Address
329+ {
330+ let octets = [ 7 , 5 , 3 , 1 ] ;
331+ let core_ipv4_addr = StdIpv4Addr :: from ( octets) ;
332+ assert_eq ! ( Ipv4Address :: from( core_ipv4_addr) . octets( ) , octets) ;
333+ assert_eq ! (
334+ unsafe { IpAddress :: from( core_ipv4_addr) . v4. octets( ) } ,
335+ octets
336+ ) ;
337+ }
338+ // StdIpv6Addr -> Ipv6Address
339+ {
340+ let octets = [ 7 , 5 , 3 , 1 , 6 , 3 , 8 , 5 , 2 , 5 , 2 , 7 , 3 , 5 , 2 , 6 ] ;
341+ let core_ipv6_addr = StdIpv6Addr :: from ( octets) ;
342+ assert_eq ! ( Ipv6Address :: from( core_ipv6_addr) . octets( ) , octets) ;
343+ assert_eq ! (
344+ unsafe { IpAddress :: from( core_ipv6_addr) . v6. octets( ) } ,
345+ octets
346+ ) ;
347+ }
348+ // StdIpAddr -> IpAddress
349+ {
350+ let octets = [ 8 , 8 , 2 , 6 ] ;
351+ let core_ip_addr = StdIpAddr :: from ( octets) ;
352+ assert_eq ! ( unsafe { IpAddress :: from( core_ip_addr) . v4. octets( ) } , octets) ;
353+ }
354+ // octets -> MacAddress
355+ {
356+ let octets = [ 8 , 8 , 2 , 6 , 6 , 7 ] ;
357+ let uefi_mac_addr = MacAddress :: from ( octets) ;
358+ assert_eq ! ( uefi_mac_addr. octets( ) [ 0 ..6 ] , octets) ;
359+ }
360+ // octets -> MacAddress
361+ {
362+ let octets = [
363+ 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 ,
364+ 0 , 0 , 0 , 0 , 42 ,
365+ ] ;
366+ let uefi_mac_addr = MacAddress :: from ( octets) ;
367+ assert_eq ! ( uefi_mac_addr. octets( ) , octets) ;
368+ }
369+ }
243370}
0 commit comments