Rollup merge of #44395 - jcdyer:ip-constructors, r=alexcrichton

Ipv4Addr and Ipv6Addr convenience constructors.

Introduce convenience constructors for common types.

This introduces the following constructors:

* Ipv6Addr::localhost()
* Ipv6Addr::unspecified()
* Ipv4Addr::localhost()
* Ipv4Addr::unspecified()

The recently added `From` implementations were nice for avoiding the fallibility of conversions from strings like `"127.0.0.1".parse().unwrap()`, and `"::1".parse().unwrap()`, but while the Ipv4 version is roughly comparable in verbosity, the Ipv6 version lacks zero-segment elision, which makes it significantly more awkward: `[0, 0, 0, 0, 0, 0, 0, 0].into()`.  While there isn't a clear way to introduce zero elision to type that can infallibly be converted into Ipv6 addresses, this PR resolves the problem for the two most commonly used addresses, which, incidentally, are the ones that suffer the most from the lack of zero-segment elision.

This change is dead simple, and introduces no backwards incompatibility.

See also, [this topic on the inernals board](https://internals.rust-lang.org/t/pre-rfc-convenience-ip-address-constructors/5878)
This commit is contained in:
Alex Crichton 2017-09-16 09:16:48 -05:00
commit 256b8879cc

View File

@ -10,7 +10,7 @@
#![unstable(feature = "ip", reason = "extra functionality has not been \
scrutinized to the level that it should \
be stable",
be to be stable",
issue = "27709")]
use cmp::Ordering;
@ -342,6 +342,42 @@ impl Ipv4Addr {
}
}
/// Creates a new IPv4 address with the address pointing to localhost: 127.0.0.1.
///
/// # Examples
///
/// ```
/// #![feature(ip_constructors)]
/// use std::net::Ipv4Addr;
///
/// let addr = Ipv4Addr::localhost();
/// assert_eq!(addr, Ipv4Addr::new(127, 0, 0, 1));
/// ```
#[unstable(feature = "ip_constructors",
reason = "requires greater scrutiny before stabilization",
issue = "44582")]
pub fn localhost() -> Ipv4Addr {
Ipv4Addr::new(127, 0, 0, 1)
}
/// Creates a new IPv4 address representing an unspecified address: 0.0.0.0
///
/// # Examples
///
/// ```
/// #![feature(ip_constructors)]
/// use std::net::Ipv4Addr;
///
/// let addr = Ipv4Addr::unspecified();
/// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0));
/// ```
#[unstable(feature = "ip_constructors",
reason = "requires greater scrutiny before stabilization",
issue = "44582")]
pub fn unspecified() -> Ipv4Addr {
Ipv4Addr::new(0, 0, 0, 0)
}
/// Returns the four eight-bit integers that make up this address.
///
/// # Examples
@ -788,6 +824,42 @@ impl Ipv6Addr {
Ipv6Addr { inner: addr }
}
/// Creates a new IPv6 address representing localhost: `::1`.
///
/// # Examples
///
/// ```
/// #![feature(ip_constructors)]
/// use std::net::Ipv6Addr;
///
/// let addr = Ipv6Addr::localhost();
/// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
/// ```
#[unstable(feature = "ip_constructors",
reason = "requires greater scrutiny before stabilization",
issue = "44582")]
pub fn localhost() -> Ipv6Addr {
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)
}
/// Creates a new IPv6 address representing the unspecified address: `::`
///
/// # Examples
///
/// ```
/// #![feature(ip_constructors)]
/// use std::net::Ipv6Addr;
///
/// let addr = Ipv6Addr::unspecified();
/// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
/// ```
#[unstable(feature = "ip_constructors",
reason = "requires greater scrutiny before stabilization",
issue = "44582")]
pub fn unspecified() -> Ipv6Addr {
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)
}
/// Returns the eight 16-bit segments that make up this address.
///
/// # Examples
@ -1681,6 +1753,22 @@ mod tests {
assert_eq!(Ipv6Addr::from(0x112233445566778899aabbccddeeff11u128), a);
}
#[test]
fn ipv4_from_constructors() {
assert_eq!(Ipv4Addr::localhost(), Ipv4Addr::new(127, 0, 0, 1));
assert!(Ipv4Addr::localhost().is_loopback());
assert_eq!(Ipv4Addr::unspecified(), Ipv4Addr::new(0, 0, 0, 0));
assert!(Ipv4Addr::unspecified().is_unspecified());
}
#[test]
fn ipv6_from_contructors() {
assert_eq!(Ipv6Addr::localhost(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
assert!(Ipv6Addr::localhost().is_loopback());
assert_eq!(Ipv6Addr::unspecified(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert!(Ipv6Addr::unspecified().is_unspecified());
}
#[test]
fn ipv4_from_octets() {
assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1))