11
11
use core:: fmt:: { self , Debug , 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,7 +42,20 @@ 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
/// 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`]
39
59
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
40
60
#[ repr( transparent) ]
41
61
pub struct Ipv6Address ( pub [ u8 ; 16 ] ) ;
@@ -60,12 +80,27 @@ impl From<Ipv6Address> for core::net::Ipv6Addr {
60
80
}
61
81
}
62
82
83
+ impl From < [ u8 ; 16 ] > for Ipv6Address {
84
+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
85
+ Self ( octets)
86
+ }
87
+ }
88
+
63
89
/// An IPv4 or IPv6 internet protocol address that is ABI compatible with EFI.
64
90
///
65
91
/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
66
92
/// type is defined in the same way as edk2 for compatibility with C code. Note
67
93
/// that this is an untagged union, so there's no way to tell which type of
68
94
/// 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`]
69
104
#[ derive( Clone , Copy ) ]
70
105
#[ repr( C ) ]
71
106
pub union IpAddress {
@@ -135,6 +170,30 @@ impl From<core::net::IpAddr> for IpAddress {
135
170
}
136
171
}
137
172
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
+
138
197
/// UEFI Media Access Control (MAC) address.
139
198
///
140
199
/// UEFI supports multiple network protocols and hardware types, not just
@@ -144,6 +203,13 @@ impl From<core::net::IpAddr> for IpAddress {
144
203
///
145
204
/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
146
205
/// 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`]
147
213
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
148
214
#[ repr( transparent) ]
149
215
pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -171,6 +237,13 @@ impl From<MacAddress> for [u8; 6] {
171
237
}
172
238
}
173
239
240
+ // UEFI MAC addresses.
241
+ impl From < [ u8 ; 32 ] > for MacAddress {
242
+ fn from ( octets : [ u8 ; 32 ] ) -> Self {
243
+ Self ( octets)
244
+ }
245
+ }
246
+
174
247
#[ cfg( test) ]
175
248
mod tests {
176
249
use super :: * ;
@@ -223,4 +296,64 @@ mod tests {
223
296
assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
224
297
assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
225
298
}
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
+ }
226
359
}
0 commit comments