Rollup merge of #130629 - Dirbaio:net-from-octets, r=tgross35
core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments. Adds: - `Ipv4Address::from_octets([u8;4])` - `Ipv6Address::from_octets([u8;16])` - `Ipv6Address::from_segments([u16;8])` equivalent to the existing `From` impls. Advantages: - Consistent with `to_bits, from_bits`. - More discoverable than the `From` impls. - Helps with type inference: it's common to want to convert byte slices to IP addrs. If you try this ```rust fn foo(x: &[u8]) -> Ipv4Addr { Ipv4Addr::from(foo.try_into().unwrap()) } ``` it [doesn't work](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0e2873312de275a58fa6e33d1b213bec). You have to write `Ipv4Addr::from(<[u8;4]>::try_from(x).unwrap())` instead, which is not great. With `from_octets` it is able to infer the right types. Found this while porting [smoltcp](https://github.com/smoltcp-rs/smoltcp/) from its own IP address types to the `core::net` types. ~~Tracking issues #27709 #76205~~ Tracking issue: https://github.com/rust-lang/rust/issues/131360
This commit is contained in:
commit
e01eae72da
@ -600,6 +600,24 @@ pub const fn from_bits(bits: u32) -> Ipv4Addr {
|
||||
self.octets
|
||||
}
|
||||
|
||||
/// Creates an `Ipv4Addr` from a four element byte array.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip_from)]
|
||||
/// use std::net::Ipv4Addr;
|
||||
///
|
||||
/// let addr = Ipv4Addr::from_octets([13u8, 12u8, 11u8, 10u8]);
|
||||
/// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr);
|
||||
/// ```
|
||||
#[unstable(feature = "ip_from", issue = "131360")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn from_octets(octets: [u8; 4]) -> Ipv4Addr {
|
||||
Ipv4Addr { octets }
|
||||
}
|
||||
|
||||
/// Returns [`true`] for the special 'unspecified' address (`0.0.0.0`).
|
||||
///
|
||||
/// This property is defined in _UNIX Network Programming, Second Edition_,
|
||||
@ -1400,6 +1418,34 @@ pub const fn from_bits(bits: u128) -> Ipv6Addr {
|
||||
]
|
||||
}
|
||||
|
||||
/// Creates an `Ipv6Addr` from an eight element 16-bit array.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip_from)]
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// let addr = Ipv6Addr::from_segments([
|
||||
/// 0x20du16, 0x20cu16, 0x20bu16, 0x20au16,
|
||||
/// 0x209u16, 0x208u16, 0x207u16, 0x206u16,
|
||||
/// ]);
|
||||
/// assert_eq!(
|
||||
/// Ipv6Addr::new(
|
||||
/// 0x20d, 0x20c, 0x20b, 0x20a,
|
||||
/// 0x209, 0x208, 0x207, 0x206,
|
||||
/// ),
|
||||
/// addr
|
||||
/// );
|
||||
/// ```
|
||||
#[unstable(feature = "ip_from", issue = "131360")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn from_segments(segments: [u16; 8]) -> Ipv6Addr {
|
||||
let [a, b, c, d, e, f, g, h] = segments;
|
||||
Ipv6Addr::new(a, b, c, d, e, f, g, h)
|
||||
}
|
||||
|
||||
/// Returns [`true`] for the special 'unspecified' address (`::`).
|
||||
///
|
||||
/// This property is defined in [IETF RFC 4291].
|
||||
@ -1932,7 +1978,7 @@ pub const fn to_canonical(&self) -> IpAddr {
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).octets(),
|
||||
/// [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
/// [0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
/// ```
|
||||
#[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
|
||||
#[stable(feature = "ipv6_to_octets", since = "1.12.0")]
|
||||
@ -1941,6 +1987,33 @@ pub const fn to_canonical(&self) -> IpAddr {
|
||||
pub const fn octets(&self) -> [u8; 16] {
|
||||
self.octets
|
||||
}
|
||||
|
||||
/// Creates an `Ipv6Addr` from a sixteen element byte array.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip_from)]
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// let addr = Ipv6Addr::from_octets([
|
||||
/// 0x19u8, 0x18u8, 0x17u8, 0x16u8, 0x15u8, 0x14u8, 0x13u8, 0x12u8,
|
||||
/// 0x11u8, 0x10u8, 0x0fu8, 0x0eu8, 0x0du8, 0x0cu8, 0x0bu8, 0x0au8,
|
||||
/// ]);
|
||||
/// assert_eq!(
|
||||
/// Ipv6Addr::new(
|
||||
/// 0x1918, 0x1716, 0x1514, 0x1312,
|
||||
/// 0x1110, 0x0f0e, 0x0d0c, 0x0b0a,
|
||||
/// ),
|
||||
/// addr
|
||||
/// );
|
||||
/// ```
|
||||
#[unstable(feature = "ip_from", issue = "131360")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn from_octets(octets: [u8; 16]) -> Ipv6Addr {
|
||||
Ipv6Addr { octets }
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes an Ipv6Addr, conforming to the canonical style described by
|
||||
@ -2113,15 +2186,13 @@ fn from(ip: u128) -> Ipv6Addr {
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// let addr = Ipv6Addr::from([
|
||||
/// 25u8, 24u8, 23u8, 22u8, 21u8, 20u8, 19u8, 18u8,
|
||||
/// 17u8, 16u8, 15u8, 14u8, 13u8, 12u8, 11u8, 10u8,
|
||||
/// 0x19u8, 0x18u8, 0x17u8, 0x16u8, 0x15u8, 0x14u8, 0x13u8, 0x12u8,
|
||||
/// 0x11u8, 0x10u8, 0x0fu8, 0x0eu8, 0x0du8, 0x0cu8, 0x0bu8, 0x0au8,
|
||||
/// ]);
|
||||
/// assert_eq!(
|
||||
/// Ipv6Addr::new(
|
||||
/// 0x1918, 0x1716,
|
||||
/// 0x1514, 0x1312,
|
||||
/// 0x1110, 0x0f0e,
|
||||
/// 0x0d0c, 0x0b0a
|
||||
/// 0x1918, 0x1716, 0x1514, 0x1312,
|
||||
/// 0x1110, 0x0f0e, 0x0d0c, 0x0b0a,
|
||||
/// ),
|
||||
/// addr
|
||||
/// );
|
||||
@ -2142,15 +2213,13 @@ fn from(ip: u128) -> Ipv6Addr {
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// let addr = Ipv6Addr::from([
|
||||
/// 525u16, 524u16, 523u16, 522u16,
|
||||
/// 521u16, 520u16, 519u16, 518u16,
|
||||
/// 0x20du16, 0x20cu16, 0x20bu16, 0x20au16,
|
||||
/// 0x209u16, 0x208u16, 0x207u16, 0x206u16,
|
||||
/// ]);
|
||||
/// assert_eq!(
|
||||
/// Ipv6Addr::new(
|
||||
/// 0x20d, 0x20c,
|
||||
/// 0x20b, 0x20a,
|
||||
/// 0x209, 0x208,
|
||||
/// 0x207, 0x206
|
||||
/// 0x20d, 0x20c, 0x20b, 0x20a,
|
||||
/// 0x209, 0x208, 0x207, 0x206,
|
||||
/// ),
|
||||
/// addr
|
||||
/// );
|
||||
@ -2172,15 +2241,13 @@ fn from(ip: u128) -> Ipv6Addr {
|
||||
/// use std::net::{IpAddr, Ipv6Addr};
|
||||
///
|
||||
/// let addr = IpAddr::from([
|
||||
/// 25u8, 24u8, 23u8, 22u8, 21u8, 20u8, 19u8, 18u8,
|
||||
/// 17u8, 16u8, 15u8, 14u8, 13u8, 12u8, 11u8, 10u8,
|
||||
/// 0x19u8, 0x18u8, 0x17u8, 0x16u8, 0x15u8, 0x14u8, 0x13u8, 0x12u8,
|
||||
/// 0x11u8, 0x10u8, 0x0fu8, 0x0eu8, 0x0du8, 0x0cu8, 0x0bu8, 0x0au8,
|
||||
/// ]);
|
||||
/// assert_eq!(
|
||||
/// IpAddr::V6(Ipv6Addr::new(
|
||||
/// 0x1918, 0x1716,
|
||||
/// 0x1514, 0x1312,
|
||||
/// 0x1110, 0x0f0e,
|
||||
/// 0x0d0c, 0x0b0a
|
||||
/// 0x1918, 0x1716, 0x1514, 0x1312,
|
||||
/// 0x1110, 0x0f0e, 0x0d0c, 0x0b0a,
|
||||
/// )),
|
||||
/// addr
|
||||
/// );
|
||||
@ -2201,15 +2268,13 @@ fn from(ip: u128) -> Ipv6Addr {
|
||||
/// use std::net::{IpAddr, Ipv6Addr};
|
||||
///
|
||||
/// let addr = IpAddr::from([
|
||||
/// 525u16, 524u16, 523u16, 522u16,
|
||||
/// 521u16, 520u16, 519u16, 518u16,
|
||||
/// 0x20du16, 0x20cu16, 0x20bu16, 0x20au16,
|
||||
/// 0x209u16, 0x208u16, 0x207u16, 0x206u16,
|
||||
/// ]);
|
||||
/// assert_eq!(
|
||||
/// IpAddr::V6(Ipv6Addr::new(
|
||||
/// 0x20d, 0x20c,
|
||||
/// 0x20b, 0x20a,
|
||||
/// 0x209, 0x208,
|
||||
/// 0x207, 0x206
|
||||
/// 0x20d, 0x20c, 0x20b, 0x20a,
|
||||
/// 0x209, 0x208, 0x207, 0x206,
|
||||
/// )),
|
||||
/// addr
|
||||
/// );
|
||||
|
@ -50,6 +50,7 @@
|
||||
#![feature(hashmap_internals)]
|
||||
#![feature(int_roundings)]
|
||||
#![feature(ip)]
|
||||
#![feature(ip_from)]
|
||||
#![feature(is_ascii_octdigit)]
|
||||
#![feature(isqrt)]
|
||||
#![feature(iter_advance_by)]
|
||||
|
@ -494,6 +494,7 @@ macro_rules! check {
|
||||
let octets = &[$($octet),*];
|
||||
assert_eq!(&ip!($s).octets(), octets);
|
||||
assert_eq!(Ipv6Addr::from(*octets), ip!($s));
|
||||
assert_eq!(Ipv6Addr::from_octets(*octets), ip!($s));
|
||||
|
||||
let unspecified: u32 = 1 << 0;
|
||||
let loopback: u32 = 1 << 1;
|
||||
@ -846,15 +847,19 @@ fn ipv6_from_constructors() {
|
||||
|
||||
#[test]
|
||||
fn ipv4_from_octets() {
|
||||
assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1))
|
||||
assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1));
|
||||
assert_eq!(Ipv4Addr::from_octets([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ipv6_from_segments() {
|
||||
let from_u16s =
|
||||
Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]);
|
||||
let from_u16s_explicit =
|
||||
Ipv6Addr::from_segments([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]);
|
||||
let new = Ipv6Addr::new(0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff);
|
||||
assert_eq!(new, from_u16s);
|
||||
assert_eq!(new, from_u16s_explicit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -865,7 +870,15 @@ fn ipv6_from_octets() {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
|
||||
0xff,
|
||||
]);
|
||||
let from_u16s_explicit =
|
||||
Ipv6Addr::from_segments([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]);
|
||||
let from_u8s_explicit = Ipv6Addr::from_octets([
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
|
||||
0xff,
|
||||
]);
|
||||
assert_eq!(from_u16s, from_u8s);
|
||||
assert_eq!(from_u16s, from_u16s_explicit);
|
||||
assert_eq!(from_u16s_explicit, from_u8s_explicit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -915,6 +928,9 @@ fn ipv4_const() {
|
||||
const OCTETS: [u8; 4] = IP_ADDRESS.octets();
|
||||
assert_eq!(OCTETS, [127, 0, 0, 1]);
|
||||
|
||||
const FROM_OCTETS: Ipv4Addr = Ipv4Addr::from_octets(OCTETS);
|
||||
assert_eq!(IP_ADDRESS, FROM_OCTETS);
|
||||
|
||||
const IS_UNSPECIFIED: bool = IP_ADDRESS.is_unspecified();
|
||||
assert!(!IS_UNSPECIFIED);
|
||||
|
||||
@ -971,9 +987,15 @@ fn ipv6_const() {
|
||||
const SEGMENTS: [u16; 8] = IP_ADDRESS.segments();
|
||||
assert_eq!(SEGMENTS, [0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
|
||||
const FROM_SEGMENTS: Ipv6Addr = Ipv6Addr::from_segments(SEGMENTS);
|
||||
assert_eq!(IP_ADDRESS, FROM_SEGMENTS);
|
||||
|
||||
const OCTETS: [u8; 16] = IP_ADDRESS.octets();
|
||||
assert_eq!(OCTETS, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
|
||||
const FROM_OCTETS: Ipv6Addr = Ipv6Addr::from_octets(OCTETS);
|
||||
assert_eq!(IP_ADDRESS, FROM_OCTETS);
|
||||
|
||||
const IS_UNSPECIFIED: bool = IP_ADDRESS.is_unspecified();
|
||||
assert!(!IS_UNSPECIFIED);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user