@@ -12,6 +12,13 @@ use core::fmt::{self, Debug, Formatter};
12
12
use core:: net:: { IpAddr as StdIpAddr , Ipv4Addr as StdIpv4Addr , Ipv6Addr as StdIpv6Addr } ;
13
13
14
14
/// 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`]
15
22
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
16
23
#[ repr( transparent) ]
17
24
pub struct Ipv4Address ( pub [ u8 ; 4 ] ) ;
@@ -36,7 +43,20 @@ impl From<Ipv4Address> for StdIpv4Addr {
36
43
}
37
44
}
38
45
46
+ impl From < [ u8 ; 4 ] > for Ipv4Address {
47
+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
48
+ Self ( octets)
49
+ }
50
+ }
51
+
39
52
/// 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`]
40
60
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
41
61
#[ repr( transparent) ]
42
62
pub struct Ipv6Address ( pub [ u8 ; 16 ] ) ;
@@ -61,12 +81,27 @@ impl From<Ipv6Address> for StdIpv6Addr {
61
81
}
62
82
}
63
83
84
+ impl From < [ u8 ; 16 ] > for Ipv6Address {
85
+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
86
+ Self ( octets)
87
+ }
88
+ }
89
+
64
90
/// An IPv4 or IPv6 internet protocol address that is ABI compatible with EFI.
65
91
///
66
92
/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
67
93
/// type is defined in the same way as edk2 for compatibility with C code. Note
68
94
/// that this is an untagged union, so there's no way to tell which type of
69
95
/// 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`]
70
105
#[ derive( Clone , Copy ) ]
71
106
#[ repr( C ) ]
72
107
pub union IpAddress {
@@ -136,6 +171,30 @@ impl From<StdIpAddr> for IpAddress {
136
171
}
137
172
}
138
173
174
+ impl From < StdIpv4Addr > for IpAddress {
175
+ fn from ( value : StdIpv4Addr ) -> Self {
176
+ Self :: new_v4 ( value. octets ( ) )
177
+ }
178
+ }
179
+
180
+ impl From < StdIpv6Addr > for IpAddress {
181
+ fn from ( value : StdIpv6Addr ) -> Self {
182
+ Self :: new_v6 ( value. octets ( ) )
183
+ }
184
+ }
185
+
186
+ impl From < [ u8 ; 4 ] > for IpAddress {
187
+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
188
+ Self :: new_v4 ( octets)
189
+ }
190
+ }
191
+
192
+ impl From < [ u8 ; 16 ] > for IpAddress {
193
+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
194
+ Self :: new_v6 ( octets)
195
+ }
196
+ }
197
+
139
198
/// UEFI Media Access Control (MAC) address.
140
199
///
141
200
/// UEFI supports multiple network protocols and hardware types, not just
@@ -145,6 +204,13 @@ impl From<StdIpAddr> for IpAddress {
145
204
///
146
205
/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
147
206
/// address with the rest of the bytes being zero.
207
+ ///
208
+ /// # Conversions and Relation to [`core::net`]
209
+ ///
210
+ /// There is no matching type in [`core::net`] but the following [`From`]
211
+ /// implementations exist:
212
+ /// - `[u8; 6]` -> [`MacAddress`]
213
+ /// - `[u8; 32]` -> [`MacAddress`]
148
214
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
149
215
#[ repr( transparent) ]
150
216
pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -172,6 +238,13 @@ impl From<MacAddress> for [u8; 6] {
172
238
}
173
239
}
174
240
241
+ // UEFI MAC addresses.
242
+ impl From < [ u8 ; 32 ] > for MacAddress {
243
+ fn from ( octets : [ u8 ; 32 ] ) -> Self {
244
+ Self ( octets)
245
+ }
246
+ }
247
+
175
248
#[ cfg( test) ]
176
249
mod tests {
177
250
use super :: * ;
@@ -224,4 +297,64 @@ mod tests {
224
297
assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
225
298
assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
226
299
}
300
+
301
+ /// Tests the From-impls from the documentation.
302
+ #[ test]
303
+ fn test_promised_from_impls ( ) {
304
+ // octets -> Ipv4Address
305
+ {
306
+ let octets = [ 0_u8 , 1 , 2 , 3 ] ;
307
+ assert_eq ! ( Ipv4Address :: from( octets) , Ipv4Address ( octets) ) ;
308
+ let uefi_addr = IpAddress :: from ( octets) ;
309
+ assert_eq ! ( & octets, & unsafe { uefi_addr. v4. octets( ) } ) ;
310
+ }
311
+ // octets -> Ipv6Address
312
+ {
313
+ let octets = [ 0_u8 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ;
314
+ assert_eq ! ( Ipv6Address :: from( octets) , Ipv6Address ( octets) ) ;
315
+ let uefi_addr = IpAddress :: from ( octets) ;
316
+ assert_eq ! ( & octets, & unsafe { uefi_addr. v6. octets( ) } ) ;
317
+ }
318
+ // StdIpv4Addr -> Ipv4Address
319
+ {
320
+ let octets = [ 7 , 5 , 3 , 1 ] ;
321
+ let core_ipv4_addr = StdIpv4Addr :: from ( octets) ;
322
+ assert_eq ! ( Ipv4Address :: from( core_ipv4_addr) . octets( ) , octets) ;
323
+ assert_eq ! (
324
+ unsafe { IpAddress :: from( core_ipv4_addr) . v4. octets( ) } ,
325
+ octets
326
+ ) ;
327
+ }
328
+ // StdIpv6Addr -> Ipv6Address
329
+ {
330
+ let octets = [ 7 , 5 , 3 , 1 , 6 , 3 , 8 , 5 , 2 , 5 , 2 , 7 , 3 , 5 , 2 , 6 ] ;
331
+ let core_ipv6_addr = StdIpv6Addr :: from ( octets) ;
332
+ assert_eq ! ( Ipv6Address :: from( core_ipv6_addr) . octets( ) , octets) ;
333
+ assert_eq ! (
334
+ unsafe { IpAddress :: from( core_ipv6_addr) . v6. octets( ) } ,
335
+ octets
336
+ ) ;
337
+ }
338
+ // StdIpAddr -> IpAddress
339
+ {
340
+ let octets = [ 8 , 8 , 2 , 6 ] ;
341
+ let core_ip_addr = StdIpAddr :: from ( octets) ;
342
+ assert_eq ! ( unsafe { IpAddress :: from( core_ip_addr) . v4. octets( ) } , octets) ;
343
+ }
344
+ // octets -> MacAddress
345
+ {
346
+ let octets = [ 8 , 8 , 2 , 6 , 6 , 7 ] ;
347
+ let uefi_mac_addr = MacAddress :: from ( octets) ;
348
+ assert_eq ! ( uefi_mac_addr. octets( ) [ 0 ..6 ] , octets) ;
349
+ }
350
+ // octets -> MacAddress
351
+ {
352
+ let octets = [
353
+ 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 ,
354
+ 0 , 0 , 0 , 0 , 42 ,
355
+ ] ;
356
+ let uefi_mac_addr = MacAddress :: from ( octets) ;
357
+ assert_eq ! ( uefi_mac_addr. octets( ) , octets) ;
358
+ }
359
+ }
227
360
}
0 commit comments