@@ -13,6 +13,13 @@ use core::mem;
13
13
use core:: net:: { IpAddr as StdIpAddr , Ipv4Addr as StdIpv4Addr , Ipv6Addr as StdIpv6Addr } ;
14
14
15
15
/// 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`]
16
23
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
17
24
#[ repr( transparent) ]
18
25
pub struct Ipv4Address ( pub [ u8 ; 4 ] ) ;
@@ -37,7 +44,20 @@ impl From<Ipv4Address> for StdIpv4Addr {
37
44
}
38
45
}
39
46
47
+ impl From < [ u8 ; 4 ] > for Ipv4Address {
48
+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
49
+ Self ( octets)
50
+ }
51
+ }
52
+
40
53
/// 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`]
41
61
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
42
62
#[ repr( transparent) ]
43
63
pub struct Ipv6Address ( pub [ u8 ; 16 ] ) ;
@@ -62,12 +82,27 @@ impl From<Ipv6Address> for StdIpv6Addr {
62
82
}
63
83
}
64
84
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.
66
92
///
67
93
/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
68
94
/// type is defined in the same way as edk2 for compatibility with C code. Note
69
95
/// that this is an untagged union, so there's no way to tell which type of
70
96
/// 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`]
71
106
#[ derive( Clone , Copy ) ]
72
107
#[ repr( C ) ]
73
108
pub union IpAddress {
@@ -152,6 +187,30 @@ impl From<StdIpAddr> for IpAddress {
152
187
}
153
188
}
154
189
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
+
155
214
/// UEFI Media Access Control (MAC) address.
156
215
///
157
216
/// UEFI supports multiple network protocols and hardware types, not just
@@ -161,6 +220,13 @@ impl From<StdIpAddr> for IpAddress {
161
220
///
162
221
/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
163
222
/// 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`]
164
230
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
165
231
#[ repr( transparent) ]
166
232
pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -182,9 +248,10 @@ impl From<[u8; 6]> for MacAddress {
182
248
}
183
249
}
184
250
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)
188
255
}
189
256
}
190
257
@@ -240,4 +307,64 @@ mod tests {
240
307
assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
241
308
assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
242
309
}
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
+ }
243
370
}
0 commit comments