1111use core:: fmt:: { self , Debug , 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,7 +42,20 @@ 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+
3851/// An IPv6 internet protocol address.
52+ ///
53+ /// # Conversions and Relation to [`core::net`]
54+ ///
55+ /// The following [`From`] implementations exist:
56+ /// - `[u8; 16]` -> [`Ipv6Address`]
57+ /// - [`core::net::Ipv6Addr`] -> [`Ipv6Address`]
58+ /// - [`core::net::IpAddr`] -> [`Ipv6Address`]
3959#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
4060#[ repr( transparent) ]
4161pub struct Ipv6Address ( pub [ u8 ; 16 ] ) ;
@@ -60,12 +80,27 @@ impl From<Ipv6Address> for core::net::Ipv6Addr {
6080 }
6181}
6282
83+ impl From < [ u8 ; 16 ] > for Ipv6Address {
84+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
85+ Self ( octets)
86+ }
87+ }
88+
6389/// An IPv4 or IPv6 internet protocol address that is ABI compatible with EFI.
6490///
6591/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
6692/// type is defined in the same way as edk2 for compatibility with C code. Note
6793/// that this is an untagged union, so there's no way to tell which type of
6894/// address an `IpAddress` value contains without additional context.
95+ ///
96+ /// # Conversions and Relation to [`core::net`]
97+ ///
98+ /// The following [`From`] implementations exist:
99+ /// - `[u8; 4]` -> [`IpAddress`]
100+ /// - `[u8; 16]` -> [`IpAddress`]
101+ /// - [`core::net::Ipv4Addr`] -> [`IpAddress`]
102+ /// - [`core::net::Ipv6Addr`] -> [`IpAddress`]
103+ /// - [`core::net::IpAddr`] -> [`IpAddress`]
69104#[ derive( Clone , Copy ) ]
70105#[ repr( C ) ]
71106pub union IpAddress {
@@ -135,6 +170,30 @@ impl From<core::net::IpAddr> for IpAddress {
135170 }
136171}
137172
173+ impl From < core:: net:: Ipv4Addr > for IpAddress {
174+ fn from ( value : core:: net:: Ipv4Addr ) -> Self {
175+ Self :: new_v4 ( value. octets ( ) )
176+ }
177+ }
178+
179+ impl From < core:: net:: Ipv6Addr > for IpAddress {
180+ fn from ( value : core:: net:: Ipv6Addr ) -> Self {
181+ Self :: new_v6 ( value. octets ( ) )
182+ }
183+ }
184+
185+ impl From < [ u8 ; 4 ] > for IpAddress {
186+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
187+ Self :: new_v4 ( octets)
188+ }
189+ }
190+
191+ impl From < [ u8 ; 16 ] > for IpAddress {
192+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
193+ Self :: new_v6 ( octets)
194+ }
195+ }
196+
138197/// UEFI Media Access Control (MAC) address.
139198///
140199/// UEFI supports multiple network protocols and hardware types, not just
@@ -144,6 +203,13 @@ impl From<core::net::IpAddr> for IpAddress {
144203///
145204/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
146205/// address with the rest of the bytes being zero.
206+ ///
207+ /// # Conversions and Relation to [`core::net`]
208+ ///
209+ /// There is no matching type in [`core::net`] but the following [`From`]
210+ /// implementations exist:
211+ /// - `[u8; 6]` -> [`MacAddress`]
212+ /// - `[u8; 32]` -> [`MacAddress`]
147213#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
148214#[ repr( transparent) ]
149215pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -171,6 +237,13 @@ impl From<MacAddress> for [u8; 6] {
171237 }
172238}
173239
240+ // UEFI MAC addresses.
241+ impl From < [ u8 ; 32 ] > for MacAddress {
242+ fn from ( octets : [ u8 ; 32 ] ) -> Self {
243+ Self ( octets)
244+ }
245+ }
246+
174247#[ cfg( test) ]
175248mod tests {
176249 use super :: * ;
@@ -223,4 +296,64 @@ mod tests {
223296 assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
224297 assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
225298 }
299+
300+ /// Tests the From-impls from the documentation.
301+ #[ test]
302+ fn test_promised_from_impls ( ) {
303+ // octets -> Ipv4Address
304+ {
305+ let octets = [ 0_u8 , 1 , 2 , 3 ] ;
306+ assert_eq ! ( Ipv4Address :: from( octets) , Ipv4Address ( octets) ) ;
307+ let uefi_addr = IpAddress :: from ( octets) ;
308+ assert_eq ! ( & octets, & unsafe { uefi_addr. v4. octets( ) } ) ;
309+ }
310+ // octets -> Ipv6Address
311+ {
312+ let octets = [ 0_u8 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ;
313+ assert_eq ! ( Ipv6Address :: from( octets) , Ipv6Address ( octets) ) ;
314+ let uefi_addr = IpAddress :: from ( octets) ;
315+ assert_eq ! ( & octets, & unsafe { uefi_addr. v6. octets( ) } ) ;
316+ }
317+ // StdIpv4Addr -> Ipv4Address
318+ {
319+ let octets = [ 7 , 5 , 3 , 1 ] ;
320+ let core_ipv4_addr = core:: net:: Ipv4Addr :: from ( octets) ;
321+ assert_eq ! ( Ipv4Address :: from( core_ipv4_addr) . octets( ) , octets) ;
322+ assert_eq ! (
323+ unsafe { IpAddress :: from( core_ipv4_addr) . v4. octets( ) } ,
324+ octets
325+ ) ;
326+ }
327+ // StdIpv6Addr -> Ipv6Address
328+ {
329+ let octets = [ 7 , 5 , 3 , 1 , 6 , 3 , 8 , 5 , 2 , 5 , 2 , 7 , 3 , 5 , 2 , 6 ] ;
330+ let core_ipv6_addr = core:: net:: Ipv6Addr :: from ( octets) ;
331+ assert_eq ! ( Ipv6Address :: from( core_ipv6_addr) . octets( ) , octets) ;
332+ assert_eq ! (
333+ unsafe { IpAddress :: from( core_ipv6_addr) . v6. octets( ) } ,
334+ octets
335+ ) ;
336+ }
337+ // StdIpAddr -> IpAddress
338+ {
339+ let octets = [ 8 , 8 , 2 , 6 ] ;
340+ let core_ip_addr = core:: net:: IpAddr :: from ( octets) ;
341+ assert_eq ! ( unsafe { IpAddress :: from( core_ip_addr) . v4. octets( ) } , octets) ;
342+ }
343+ // octets -> MacAddress
344+ {
345+ let octets = [ 8 , 8 , 2 , 6 , 6 , 7 ] ;
346+ let uefi_mac_addr = MacAddress :: from ( octets) ;
347+ assert_eq ! ( uefi_mac_addr. octets( ) [ 0 ..6 ] , octets) ;
348+ }
349+ // octets -> MacAddress
350+ {
351+ let octets = [
352+ 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 ,
353+ 0 , 0 , 0 , 0 , 42 ,
354+ ] ;
355+ let uefi_mac_addr = MacAddress :: from ( octets) ;
356+ assert_eq ! ( uefi_mac_addr. octets( ) , octets) ;
357+ }
358+ }
226359}
0 commit comments