@@ -12,6 +12,13 @@ use core::fmt;
1212use core:: fmt:: { Debug , Formatter } ;
1313
1414/// An IPv4 internet protocol address.
15+ ///
16+ /// # Conversions and Relation to [`core::net`]
17+ ///
18+ /// The following [`From`] implementations exist:
19+ /// - `[u8; 4]` -> [`Ipv4Address`]
20+ /// - [`core::net::Ipv4Addr`] -> [`Ipv4Address`]
21+ /// - [`core::net::IpAddr`] -> [`Ipv4Address`]
1522#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
1623#[ repr( transparent) ]
1724pub struct Ipv4Address ( pub [ u8 ; 4 ] ) ;
@@ -36,7 +43,20 @@ impl From<Ipv4Address> for core::net::Ipv4Addr {
3643 }
3744}
3845
46+ impl From < [ u8 ; 4 ] > for Ipv4Address {
47+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
48+ Self ( octets)
49+ }
50+ }
51+
3952/// An IPv6 internet protocol address.
53+ ///
54+ /// # Conversions and Relation to [`core::net`]
55+ ///
56+ /// The following [`From`] implementations exist:
57+ /// - `[u8; 16]` -> [`Ipv6Address`]
58+ /// - [`core::net::Ipv6Addr`] -> [`Ipv6Address`]
59+ /// - [`core::net::IpAddr`] -> [`Ipv6Address`]
4060#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
4161#[ repr( transparent) ]
4262pub struct Ipv6Address ( pub [ u8 ; 16 ] ) ;
@@ -61,12 +81,27 @@ impl From<Ipv6Address> for core::net::Ipv6Addr {
6181 }
6282}
6383
84+ impl From < [ u8 ; 16 ] > for Ipv6Address {
85+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
86+ Self ( octets)
87+ }
88+ }
89+
6490/// An IPv4 or IPv6 internet protocol address that is ABI compatible with EFI.
6591///
6692/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
6793/// type is defined in the same way as edk2 for compatibility with C code. Note
6894/// that this is an untagged union, so there's no way to tell which type of
6995/// address an `IpAddress` value contains without additional context.
96+ ///
97+ /// # Conversions and Relation to [`core::net`]
98+ ///
99+ /// The following [`From`] implementations exist:
100+ /// - `[u8; 4]` -> [`IpAddress`]
101+ /// - `[u8; 16]` -> [`IpAddress`]
102+ /// - [`core::net::Ipv4Addr`] -> [`IpAddress`]
103+ /// - [`core::net::Ipv6Addr`] -> [`IpAddress`]
104+ /// - [`core::net::IpAddr`] -> [`IpAddress`]
70105#[ derive( Clone , Copy ) ]
71106#[ repr( C ) ]
72107pub union IpAddress {
@@ -128,6 +163,30 @@ impl From<core::net::IpAddr> for IpAddress {
128163 }
129164}
130165
166+ impl From < core:: net:: Ipv4Addr > for IpAddress {
167+ fn from ( value : core:: net:: Ipv4Addr ) -> Self {
168+ Self :: new_v4 ( value. octets ( ) )
169+ }
170+ }
171+
172+ impl From < core:: net:: Ipv6Addr > for IpAddress {
173+ fn from ( value : core:: net:: Ipv6Addr ) -> Self {
174+ Self :: new_v6 ( value. octets ( ) )
175+ }
176+ }
177+
178+ impl From < [ u8 ; 4 ] > for IpAddress {
179+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
180+ Self :: new_v4 ( octets)
181+ }
182+ }
183+
184+ impl From < [ u8 ; 16 ] > for IpAddress {
185+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
186+ Self :: new_v6 ( octets)
187+ }
188+ }
189+
131190/// UEFI Media Access Control (MAC) address.
132191///
133192/// UEFI supports multiple network protocols and hardware types, not just
@@ -137,6 +196,13 @@ impl From<core::net::IpAddr> for IpAddress {
137196///
138197/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
139198/// address with the rest of the bytes being zero.
199+ ///
200+ /// # Conversions and Relation to [`core::net`]
201+ ///
202+ /// There is no matching type in [`core::net`] but the following [`From`]
203+ /// implementations exist:
204+ /// - `[u8; 6]` <-> [`MacAddress`]
205+ /// - `[u8; 32]` -> [`MacAddress`]
140206#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
141207#[ repr( transparent) ]
142208pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -149,7 +215,7 @@ impl MacAddress {
149215 }
150216}
151217
152- // Normal/typical MAC addresses, such as in Ethernet .
218+ // Normal Ethernet MAC address .
153219impl From < [ u8 ; 6 ] > for MacAddress {
154220 fn from ( octets : [ u8 ; 6 ] ) -> Self {
155221 let mut buffer = [ 0 ; 32 ] ;
@@ -158,12 +224,20 @@ impl From<[u8; 6]> for MacAddress {
158224 }
159225}
160226
227+ // Normal Ethernet MAC address.
161228impl From < MacAddress > for [ u8 ; 6 ] {
162229 fn from ( MacAddress ( o) : MacAddress ) -> Self {
163230 [ o[ 0 ] , o[ 1 ] , o[ 2 ] , o[ 3 ] , o[ 4 ] , o[ 5 ] ]
164231 }
165232}
166233
234+ // UEFI MAC addresses.
235+ impl From < [ u8 ; 32 ] > for MacAddress {
236+ fn from ( octets : [ u8 ; 32 ] ) -> Self {
237+ Self ( octets)
238+ }
239+ }
240+
167241#[ cfg( test) ]
168242mod tests {
169243 use super :: * ;
@@ -216,4 +290,64 @@ mod tests {
216290 assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
217291 assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
218292 }
293+
294+ /// Tests the From-impls from the documentation.
295+ #[ test]
296+ fn test_promised_from_impls ( ) {
297+ // octets -> Ipv4Address
298+ {
299+ let octets = [ 0_u8 , 1 , 2 , 3 ] ;
300+ assert_eq ! ( Ipv4Address :: from( octets) , Ipv4Address ( octets) ) ;
301+ let uefi_addr = IpAddress :: from ( octets) ;
302+ assert_eq ! ( & octets, & unsafe { uefi_addr. v4. octets( ) } ) ;
303+ }
304+ // octets -> Ipv6Address
305+ {
306+ let octets = [ 0_u8 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ;
307+ assert_eq ! ( Ipv6Address :: from( octets) , Ipv6Address ( octets) ) ;
308+ let uefi_addr = IpAddress :: from ( octets) ;
309+ assert_eq ! ( & octets, & unsafe { uefi_addr. v6. octets( ) } ) ;
310+ }
311+ // StdIpv4Addr -> Ipv4Address
312+ {
313+ let octets = [ 7 , 5 , 3 , 1 ] ;
314+ let core_ipv4_addr = core:: net:: Ipv4Addr :: from ( octets) ;
315+ assert_eq ! ( Ipv4Address :: from( core_ipv4_addr) . octets( ) , octets) ;
316+ assert_eq ! (
317+ unsafe { IpAddress :: from( core_ipv4_addr) . v4. octets( ) } ,
318+ octets
319+ ) ;
320+ }
321+ // StdIpv6Addr -> Ipv6Address
322+ {
323+ let octets = [ 7 , 5 , 3 , 1 , 6 , 3 , 8 , 5 , 2 , 5 , 2 , 7 , 3 , 5 , 2 , 6 ] ;
324+ let core_ipv6_addr = core:: net:: Ipv6Addr :: from ( octets) ;
325+ assert_eq ! ( Ipv6Address :: from( core_ipv6_addr) . octets( ) , octets) ;
326+ assert_eq ! (
327+ unsafe { IpAddress :: from( core_ipv6_addr) . v6. octets( ) } ,
328+ octets
329+ ) ;
330+ }
331+ // StdIpAddr -> IpAddress
332+ {
333+ let octets = [ 8 , 8 , 2 , 6 ] ;
334+ let core_ip_addr = core:: net:: IpAddr :: from ( octets) ;
335+ assert_eq ! ( unsafe { IpAddress :: from( core_ip_addr) . v4. octets( ) } , octets) ;
336+ }
337+ // octets -> MacAddress
338+ {
339+ let octets = [ 8 , 8 , 2 , 6 , 6 , 7 ] ;
340+ let uefi_mac_addr = MacAddress :: from ( octets) ;
341+ assert_eq ! ( uefi_mac_addr. octets( ) [ 0 ..6 ] , octets) ;
342+ }
343+ // octets -> MacAddress
344+ {
345+ let octets = [
346+ 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 ,
347+ 0 , 0 , 0 , 0 , 42 ,
348+ ] ;
349+ let uefi_mac_addr = MacAddress :: from ( octets) ;
350+ assert_eq ! ( uefi_mac_addr. octets( ) , octets) ;
351+ }
352+ }
219353}
0 commit comments