11
11
use core:: fmt:: { self , Debug , Display , Formatter } ;
12
12
13
13
/// 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`]
14
21
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
15
22
#[ repr( transparent) ]
16
23
pub struct Ipv4Address ( pub [ u8 ; 4 ] ) ;
@@ -35,6 +42,12 @@ impl From<Ipv4Address> for core::net::Ipv4Addr {
35
42
}
36
43
}
37
44
45
+ impl From < [ u8 ; 4 ] > for Ipv4Address {
46
+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
47
+ Self ( octets)
48
+ }
49
+ }
50
+
38
51
impl Display for Ipv4Address {
39
52
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
40
53
let ip = core:: net:: Ipv4Addr :: from ( * self ) ;
@@ -43,6 +56,13 @@ impl Display for Ipv4Address {
43
56
}
44
57
45
58
/// 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`]
46
66
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
47
67
#[ repr( transparent) ]
48
68
pub struct Ipv6Address ( pub [ u8 ; 16 ] ) ;
@@ -67,6 +87,12 @@ impl From<Ipv6Address> for core::net::Ipv6Addr {
67
87
}
68
88
}
69
89
90
+ impl From < [ u8 ; 16 ] > for Ipv6Address {
91
+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
92
+ Self ( octets)
93
+ }
94
+ }
95
+
70
96
impl Display for Ipv6Address {
71
97
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
72
98
let ip = core:: net:: Ipv6Addr :: from ( * self ) ;
@@ -80,6 +106,15 @@ impl Display for Ipv6Address {
80
106
/// type is defined in the same way as edk2 for compatibility with C code. Note
81
107
/// that this is an untagged union, so there's no way to tell which type of
82
108
/// 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`]
83
118
#[ derive( Clone , Copy ) ]
84
119
#[ repr( C ) ]
85
120
pub union IpAddress {
@@ -170,6 +205,30 @@ impl From<core::net::IpAddr> for IpAddress {
170
205
}
171
206
}
172
207
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
+
173
232
/// UEFI Media Access Control (MAC) address.
174
233
///
175
234
/// UEFI supports multiple network protocols and hardware types, not just
@@ -179,6 +238,13 @@ impl From<core::net::IpAddr> for IpAddress {
179
238
///
180
239
/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
181
240
/// 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`]
182
248
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
183
249
#[ repr( transparent) ]
184
250
pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -200,7 +266,7 @@ impl MacAddress {
200
266
}
201
267
}
202
268
203
- // Normal/typical MAC addresses, such as in Ethernet .
269
+ // Normal Ethernet MAC address .
204
270
impl From < [ u8 ; 6 ] > for MacAddress {
205
271
fn from ( octets : [ u8 ; 6 ] ) -> Self {
206
272
let mut buffer = [ 0 ; 32 ] ;
@@ -209,12 +275,20 @@ impl From<[u8; 6]> for MacAddress {
209
275
}
210
276
}
211
277
278
+ // Normal Ethernet MAC address.
212
279
impl From < MacAddress > for [ u8 ; 6 ] {
213
280
fn from ( MacAddress ( o) : MacAddress ) -> Self {
214
281
[ o[ 0 ] , o[ 1 ] , o[ 2 ] , o[ 3 ] , o[ 4 ] , o[ 5 ] ]
215
282
}
216
283
}
217
284
285
+ // UEFI MAC addresses.
286
+ impl From < [ u8 ; 32 ] > for MacAddress {
287
+ fn from ( octets : [ u8 ; 32 ] ) -> Self {
288
+ Self ( octets)
289
+ }
290
+ }
291
+
218
292
#[ cfg( test) ]
219
293
mod tests {
220
294
use super :: * ;
@@ -267,4 +341,66 @@ mod tests {
267
341
assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
268
342
assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
269
343
}
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
+ }
270
406
}
0 commit comments