@@ -12,6 +12,13 @@ use core::fmt;
12
12
use core:: fmt:: { Debug , Formatter } ;
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 core::net::Ipv4Addr {
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 core::net::Ipv6Addr {
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 {
@@ -128,6 +163,30 @@ impl From<core::net::IpAddr> for IpAddress {
128
163
}
129
164
}
130
165
166
+ impl From < core:: net:: Ipv4Addr > for IpAddress {
167
+ fn from ( value : core:: net:: Ipv4Addr ) -> Self {
168
+ Self :: new_v4 ( value. octets ( ) )
169
+ }
170
+ }
171
+
172
+ impl From < core:: net:: Ipv6Addr > for IpAddress {
173
+ fn from ( value : core:: net:: Ipv6Addr ) -> Self {
174
+ Self :: new_v6 ( value. octets ( ) )
175
+ }
176
+ }
177
+
178
+ impl From < [ u8 ; 4 ] > for IpAddress {
179
+ fn from ( octets : [ u8 ; 4 ] ) -> Self {
180
+ Self :: new_v4 ( octets)
181
+ }
182
+ }
183
+
184
+ impl From < [ u8 ; 16 ] > for IpAddress {
185
+ fn from ( octets : [ u8 ; 16 ] ) -> Self {
186
+ Self :: new_v6 ( octets)
187
+ }
188
+ }
189
+
131
190
/// UEFI Media Access Control (MAC) address.
132
191
///
133
192
/// UEFI supports multiple network protocols and hardware types, not just
@@ -137,6 +196,13 @@ impl From<core::net::IpAddr> for IpAddress {
137
196
///
138
197
/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
139
198
/// address with the rest of the bytes being zero.
199
+ ///
200
+ /// # Conversions and Relation to [`core::net`]
201
+ ///
202
+ /// There is no matching type in [`core::net`] but the following [`From`]
203
+ /// implementations exist:
204
+ /// - `[u8; 6]` <-> [`MacAddress`]
205
+ /// - `[u8; 32]` -> [`MacAddress`]
140
206
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
141
207
#[ repr( transparent) ]
142
208
pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
@@ -149,7 +215,7 @@ impl MacAddress {
149
215
}
150
216
}
151
217
152
- // Normal/typical MAC addresses, such as in Ethernet .
218
+ // Normal Ethernet MAC address .
153
219
impl From < [ u8 ; 6 ] > for MacAddress {
154
220
fn from ( octets : [ u8 ; 6 ] ) -> Self {
155
221
let mut buffer = [ 0 ; 32 ] ;
@@ -158,12 +224,20 @@ impl From<[u8; 6]> for MacAddress {
158
224
}
159
225
}
160
226
227
+ // Normal Ethernet MAC address.
161
228
impl From < MacAddress > for [ u8 ; 6 ] {
162
229
fn from ( MacAddress ( o) : MacAddress ) -> Self {
163
230
[ o[ 0 ] , o[ 1 ] , o[ 2 ] , o[ 3 ] , o[ 4 ] , o[ 5 ] ]
164
231
}
165
232
}
166
233
234
+ // UEFI MAC addresses.
235
+ impl From < [ u8 ; 32 ] > for MacAddress {
236
+ fn from ( octets : [ u8 ; 32 ] ) -> Self {
237
+ Self ( octets)
238
+ }
239
+ }
240
+
167
241
#[ cfg( test) ]
168
242
mod tests {
169
243
use super :: * ;
@@ -216,4 +290,64 @@ mod tests {
216
290
assert_eq ! ( align_of:: <PackedHelper <IpAddress >>( ) , 1 ) ;
217
291
assert_eq ! ( size_of:: <PackedHelper <IpAddress >>( ) , 16 ) ;
218
292
}
293
+
294
+ /// Tests the From-impls from the documentation.
295
+ #[ test]
296
+ fn test_promised_from_impls ( ) {
297
+ // octets -> Ipv4Address
298
+ {
299
+ let octets = [ 0_u8 , 1 , 2 , 3 ] ;
300
+ assert_eq ! ( Ipv4Address :: from( octets) , Ipv4Address ( octets) ) ;
301
+ let uefi_addr = IpAddress :: from ( octets) ;
302
+ assert_eq ! ( & octets, & unsafe { uefi_addr. v4. octets( ) } ) ;
303
+ }
304
+ // octets -> Ipv6Address
305
+ {
306
+ let octets = [ 0_u8 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ;
307
+ assert_eq ! ( Ipv6Address :: from( octets) , Ipv6Address ( octets) ) ;
308
+ let uefi_addr = IpAddress :: from ( octets) ;
309
+ assert_eq ! ( & octets, & unsafe { uefi_addr. v6. octets( ) } ) ;
310
+ }
311
+ // StdIpv4Addr -> Ipv4Address
312
+ {
313
+ let octets = [ 7 , 5 , 3 , 1 ] ;
314
+ let core_ipv4_addr = core:: net:: Ipv4Addr :: from ( octets) ;
315
+ assert_eq ! ( Ipv4Address :: from( core_ipv4_addr) . octets( ) , octets) ;
316
+ assert_eq ! (
317
+ unsafe { IpAddress :: from( core_ipv4_addr) . v4. octets( ) } ,
318
+ octets
319
+ ) ;
320
+ }
321
+ // StdIpv6Addr -> Ipv6Address
322
+ {
323
+ let octets = [ 7 , 5 , 3 , 1 , 6 , 3 , 8 , 5 , 2 , 5 , 2 , 7 , 3 , 5 , 2 , 6 ] ;
324
+ let core_ipv6_addr = core:: net:: Ipv6Addr :: from ( octets) ;
325
+ assert_eq ! ( Ipv6Address :: from( core_ipv6_addr) . octets( ) , octets) ;
326
+ assert_eq ! (
327
+ unsafe { IpAddress :: from( core_ipv6_addr) . v6. octets( ) } ,
328
+ octets
329
+ ) ;
330
+ }
331
+ // StdIpAddr -> IpAddress
332
+ {
333
+ let octets = [ 8 , 8 , 2 , 6 ] ;
334
+ let core_ip_addr = core:: net:: IpAddr :: from ( octets) ;
335
+ assert_eq ! ( unsafe { IpAddress :: from( core_ip_addr) . v4. octets( ) } , octets) ;
336
+ }
337
+ // octets -> MacAddress
338
+ {
339
+ let octets = [ 8 , 8 , 2 , 6 , 6 , 7 ] ;
340
+ let uefi_mac_addr = MacAddress :: from ( octets) ;
341
+ assert_eq ! ( uefi_mac_addr. octets( ) [ 0 ..6 ] , octets) ;
342
+ }
343
+ // octets -> MacAddress
344
+ {
345
+ let octets = [
346
+ 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 ,
347
+ 0 , 0 , 0 , 0 , 42 ,
348
+ ] ;
349
+ let uefi_mac_addr = MacAddress :: from ( octets) ;
350
+ assert_eq ! ( uefi_mac_addr. octets( ) , octets) ;
351
+ }
352
+ }
219
353
}
0 commit comments