Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7933b38

Browse files
committed
uefi-raw: add convenient From impls + integration with core::net
- added missing conversions between core::net types and the uefi-raw net types - added missing conversions for "typical byte arrays"
1 parent ba719fe commit 7933b38

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

‎uefi-raw/CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88
- Added `::octets()` for `Ipv4Address`, `Ipv6Address`, and
99
`MacAddress` to streamline the API with `core::net`.
1010
- Added `::ZERO` constant for `IpAddress`
11+
- Added comprehensive integration with `core::net::{IpAddr, Ipv4Addr, Ipv6Addr}`
12+
via `From` impls to better integrate uefi-raw types `IpAddress`,
13+
`Ipv4Address`, and `Ipv6Address` with the Rust ecosystem.
14+
- Added convenient `From` impls:
15+
- `[u8; 6]` --> `MacAddress`
16+
- `[u8; 32]` --> `MacAddress`
17+
- `[u8; 4]` --> `Ipv4Address`, `IpAddress`
18+
- `[u8; 16]` --> `Ipv6Address`, `IpAddress`
1119

1220
## Changed
1321
- **Breaking:** The MSRV is now 1.85.1 and the crate uses the Rust 2024 edition.

‎uefi-raw/src/net.rs‎

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111
use core::fmt::{self, Debug, Formatter};
1212

1313
/// 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`]
1421
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
1522
#[repr(transparent)]
1623
pub struct Ipv4Address(pub [u8; 4]);
@@ -35,7 +42,20 @@ impl From<Ipv4Address> for core::net::Ipv4Addr {
3542
}
3643
}
3744

45+
impl From<[u8; 4]> for Ipv4Address {
46+
fn from(octets: [u8; 4]) -> Self {
47+
Self(octets)
48+
}
49+
}
50+
3851
/// 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`]
3959
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
4060
#[repr(transparent)]
4161
pub struct Ipv6Address(pub [u8; 16]);
@@ -60,12 +80,27 @@ impl From<Ipv6Address> for core::net::Ipv6Addr {
6080
}
6181
}
6282

83+
impl From<[u8; 16]> for Ipv6Address {
84+
fn from(octets: [u8; 16]) -> Self {
85+
Self(octets)
86+
}
87+
}
88+
6389
/// An IPv4 or IPv6 internet protocol address that is ABI compatible with EFI.
6490
///
6591
/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
6692
/// type is defined in the same way as edk2 for compatibility with C code. Note
6793
/// that this is an untagged union, so there's no way to tell which type of
6894
/// 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`]
69104
#[derive(Clone, Copy)]
70105
#[repr(C)]
71106
pub union IpAddress {
@@ -135,6 +170,30 @@ impl From<core::net::IpAddr> for IpAddress {
135170
}
136171
}
137172

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+
138197
/// UEFI Media Access Control (MAC) address.
139198
///
140199
/// UEFI supports multiple network protocols and hardware types, not just
@@ -144,6 +203,13 @@ impl From<core::net::IpAddr> for IpAddress {
144203
///
145204
/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
146205
/// 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`]
147213
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
148214
#[repr(transparent)]
149215
pub struct MacAddress(pub [u8; 32]);
@@ -171,6 +237,13 @@ impl From<MacAddress> for [u8; 6] {
171237
}
172238
}
173239

240+
// UEFI MAC addresses.
241+
impl From<[u8; 32]> for MacAddress {
242+
fn from(octets: [u8; 32]) -> Self {
243+
Self(octets)
244+
}
245+
}
246+
174247
#[cfg(test)]
175248
mod tests {
176249
use super::*;
@@ -223,4 +296,64 @@ mod tests {
223296
assert_eq!(align_of::<PackedHelper<IpAddress>>(), 1);
224297
assert_eq!(size_of::<PackedHelper<IpAddress>>(), 16);
225298
}
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+
}
226359
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /