diff --git a/Cargo.toml b/Cargo.toml index caa401b..872ad53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ categories = ["network-programming"] readme = "README.md" documentation = "https://docs.rs/ipnet" edition = "2018" +rust-version = "1.31" [features] default = ["std"] diff --git a/README.md b/README.md index 66b53bf..188a98e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Read the [documentation] for the full details. And find it on [Crates.io]. ## Release 2.0 requirements -Release 2.0 requires Rust 1.26 or later. Release 1.0 used a custom emulated 128-bit integer type (`Emu128`) to fully support IPv6 addresses. This has been replaced with Rust's built-in 128-bit integer, which is now stable as of Rust 1.26. There are reports of issues using Rust's 128-bit integers on some targets (e.g. Emscripten). If you have issues on your chosen target, please continue to use the 1.0 release until that has been resolved. +Release 2.0 requires Rust 1.31 or later. Release 1.0 used a custom emulated 128-bit integer type (`Emu128`) to fully support IPv6 addresses. This has been replaced with Rust's built-in 128-bit integer, which is now stable as of Rust 1.26. There are reports of issues using Rust's 128-bit integers on some targets (e.g. Emscripten). If you have issues on your chosen target, please continue to use the 1.0 release until that has been resolved. ## Examples diff --git a/src/ipext.rs b/src/ipext.rs index d19b920..1b187c0 100644 --- a/src/ipext.rs +++ b/src/ipext.rs @@ -4,8 +4,8 @@ //! the `Ipv4Addr` and `Ipv6Addr` types with methods to perform these //! operations. -use core::cmp::Ordering::{Less, Equal}; -use core::iter::{FusedIterator, DoubleEndedIterator}; +use core::cmp::Ordering::{Equal, Less}; +use core::iter::{DoubleEndedIterator, FusedIterator}; use core::mem; #[cfg(not(feature = "std"))] use core::net::{IpAddr, Ipv4Addr, Ipv6Addr}; @@ -78,7 +78,7 @@ pub trait IpAdd { /// assert_eq!(ip2.saturating_sub(ip1), 95); /// assert_eq!(min.saturating_sub(5), min); /// assert_eq!(ip2.saturating_sub(95), ip1); -/// +/// /// let min: Ipv6Addr = "::".parse().unwrap(); /// let ip1: Ipv6Addr = "fd00::5".parse().unwrap(); /// let ip2: Ipv6Addr = "fd00::64".parse().unwrap(); @@ -110,7 +110,7 @@ pub trait IpSub { /// /// assert_eq!(ip.bitand(mask), res); /// assert_eq!(ip.bitand(0xffff0000), res); -/// +/// /// let ip: Ipv6Addr = "fd00:1234::1".parse().unwrap(); /// let mask: Ipv6Addr = "ffff::".parse().unwrap(); /// let res: Ipv6Addr = "fd00::".parse().unwrap(); @@ -140,7 +140,7 @@ pub trait IpBitAnd { /// /// assert_eq!(ip.bitor(mask), res); /// assert_eq!(ip.bitor(0x000000ff), res); -/// +/// /// let ip: Ipv6Addr = "fd00::1".parse().unwrap(); /// let mask: Ipv6Addr = "::ffff:ffff".parse().unwrap(); /// let res: Ipv6Addr = "fd00::ffff:ffff".parse().unwrap(); @@ -154,7 +154,7 @@ pub trait IpBitOr { } macro_rules! ip_add_impl { - ($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => ( + ($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => { impl IpAdd<$rhs> for $lhs { type Output = $output; @@ -164,11 +164,11 @@ macro_rules! ip_add_impl { (lhs.saturating_add(rhs.into())).into() } } - ) + }; } macro_rules! ip_sub_impl { - ($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => ( + ($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => { impl IpSub<$rhs> for $lhs { type Output = $output; @@ -178,7 +178,7 @@ macro_rules! ip_sub_impl { (lhs.saturating_sub(rhs.into())).into() } } - ) + }; } ip_add_impl!(Ipv4Addr, u32, Ipv4Addr, u32); @@ -333,7 +333,7 @@ pub struct Ipv4AddrRange { /// /// # Examples /// -/// ``` +/// ``` /// # #[cfg(not(feature = "std"))] /// # use core::net::Ipv6Addr; /// # #[cfg(feature = "std")] @@ -385,7 +385,7 @@ impl Ipv4AddrRange { let count: u32 = self.end.saturating_sub(self.start); let count = count as u64 + 1; // Never overflows count - }, + } Some(Equal) => 1, _ => 0, } @@ -408,7 +408,7 @@ impl Ipv6AddrRange { let count = self.end.saturating_sub(self.start); // May overflow or panic count + 1 - }, + } Some(Equal) => 1, _ => 0, } @@ -416,7 +416,10 @@ impl Ipv6AddrRange { /// True only if count_u128 does not overflow fn can_count_u128(&self) -> bool { self.start != Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) - || self.end != Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff) + || self.end + != Ipv6Addr::new( + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + ) } } @@ -481,11 +484,11 @@ impl Iterator for Ipv4AddrRange { Some(Less) => { let next = self.start.add_one(); Some(mem::replace(&mut self.start, next)) - }, + } Some(Equal) => { self.end.replace_zero(); Some(self.start.replace_one()) - }, + } _ => None, } } @@ -509,9 +512,9 @@ impl Iterator for Ipv4AddrRange { // emulate standard overflow/panic behavior core::usize::MAX + 2 + count as usize } - }, + } Some(Equal) => 1, - _ => 0 + _ => 0, } } @@ -529,7 +532,7 @@ impl Iterator for Ipv4AddrRange { fn min(self) -> Option { match self.start.partial_cmp(&self.end) { Some(Less) | Some(Equal) => Some(self.start), - _ => None + _ => None, } } @@ -569,11 +572,11 @@ impl Iterator for Ipv6AddrRange { Some(Less) => { let next = self.start.add_one(); Some(mem::replace(&mut self.start, next)) - }, + } Some(Equal) => { self.end.replace_zero(); Some(self.start.replace_one()) - }, + } _ => None, } } @@ -605,7 +608,7 @@ impl Iterator for Ipv6AddrRange { fn min(self) -> Option { match self.start.partial_cmp(&self.end) { Some(Less) | Some(Equal) => Some(self.start), - _ => None + _ => None, } } @@ -670,12 +673,12 @@ impl DoubleEndedIterator for Ipv4AddrRange { Some(Less) => { let next_back = self.end.sub_one(); Some(mem::replace(&mut self.end, next_back)) - }, + } Some(Equal) => { self.end.replace_zero(); Some(self.start.replace_one()) - }, - _ => None + } + _ => None, } } fn nth_back(&mut self, n: usize) -> Option { @@ -702,12 +705,12 @@ impl DoubleEndedIterator for Ipv6AddrRange { Some(Less) => { let next_back = self.end.sub_one(); Some(mem::replace(&mut self.end, next_back)) - }, + } Some(Equal) => { self.end.replace_zero(); Some(self.start.replace_one()) - }, - _ => None + } + _ => None, } } fn nth_back(&mut self, n: usize) -> Option { @@ -718,8 +721,7 @@ impl DoubleEndedIterator for Ipv6AddrRange { self.end.replace_zero(); self.start.replace_one(); None - } - else if n == count - 1 { + } else if n == count - 1 { self.end.replace_zero(); Some(self.start.replace_one()) } else { @@ -743,28 +745,31 @@ impl FusedIterator for Ipv6AddrRange {} #[cfg(test)] mod tests { + use super::*; use alloc::vec::Vec; - use core::str::FromStr; #[cfg(not(feature = "std"))] use core::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + use core::str::FromStr; #[cfg(feature = "std")] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; - use super::*; #[test] fn test_ipaddrrange() { // Next, Next-Back let i = Ipv4AddrRange::new( Ipv4Addr::from_str("10.0.0.0").unwrap(), - Ipv4Addr::from_str("10.0.0.3").unwrap() + Ipv4Addr::from_str("10.0.0.3").unwrap(), ); - assert_eq!(i.collect::>(), vec![ - Ipv4Addr::from_str("10.0.0.0").unwrap(), - Ipv4Addr::from_str("10.0.0.1").unwrap(), - Ipv4Addr::from_str("10.0.0.2").unwrap(), - Ipv4Addr::from_str("10.0.0.3").unwrap(), - ]); + assert_eq!( + i.collect::>(), + vec![ + Ipv4Addr::from_str("10.0.0.0").unwrap(), + Ipv4Addr::from_str("10.0.0.1").unwrap(), + Ipv4Addr::from_str("10.0.0.2").unwrap(), + Ipv4Addr::from_str("10.0.0.3").unwrap(), + ] + ); let mut v = i.collect::>(); v.reverse(); @@ -772,25 +777,31 @@ mod tests { let i = Ipv4AddrRange::new( Ipv4Addr::from_str("255.255.255.254").unwrap(), - Ipv4Addr::from_str("255.255.255.255").unwrap() + Ipv4Addr::from_str("255.255.255.255").unwrap(), ); - assert_eq!(i.collect::>(), vec![ - Ipv4Addr::from_str("255.255.255.254").unwrap(), - Ipv4Addr::from_str("255.255.255.255").unwrap(), - ]); + assert_eq!( + i.collect::>(), + vec![ + Ipv4Addr::from_str("255.255.255.254").unwrap(), + Ipv4Addr::from_str("255.255.255.255").unwrap(), + ] + ); let i = Ipv6AddrRange::new( Ipv6Addr::from_str("fd00::").unwrap(), Ipv6Addr::from_str("fd00::3").unwrap(), ); - assert_eq!(i.collect::>(), vec![ - Ipv6Addr::from_str("fd00::").unwrap(), - Ipv6Addr::from_str("fd00::1").unwrap(), - Ipv6Addr::from_str("fd00::2").unwrap(), - Ipv6Addr::from_str("fd00::3").unwrap(), - ]); + assert_eq!( + i.collect::>(), + vec![ + Ipv6Addr::from_str("fd00::").unwrap(), + Ipv6Addr::from_str("fd00::1").unwrap(), + Ipv6Addr::from_str("fd00::2").unwrap(), + Ipv6Addr::from_str("fd00::3").unwrap(), + ] + ); let mut v = i.collect::>(); v.reverse(); @@ -801,48 +812,60 @@ mod tests { Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), ); - assert_eq!(i.collect::>(), vec![ - Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(), - Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), - ]); - + assert_eq!( + i.collect::>(), + vec![ + Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(), + Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), + ] + ); + let i = IpAddrRange::from(Ipv4AddrRange::new( Ipv4Addr::from_str("10.0.0.0").unwrap(), Ipv4Addr::from_str("10.0.0.3").unwrap(), )); - assert_eq!(i.collect::>(), vec![ - IpAddr::from_str("10.0.0.0").unwrap(), - IpAddr::from_str("10.0.0.1").unwrap(), - IpAddr::from_str("10.0.0.2").unwrap(), - IpAddr::from_str("10.0.0.3").unwrap(), - ]); + assert_eq!( + i.collect::>(), + vec![ + IpAddr::from_str("10.0.0.0").unwrap(), + IpAddr::from_str("10.0.0.1").unwrap(), + IpAddr::from_str("10.0.0.2").unwrap(), + IpAddr::from_str("10.0.0.3").unwrap(), + ] + ); let mut v = i.collect::>(); v.reverse(); assert_eq!(v, i.rev().collect::>()); - + let i = IpAddrRange::from(Ipv4AddrRange::new( Ipv4Addr::from_str("255.255.255.254").unwrap(), - Ipv4Addr::from_str("255.255.255.255").unwrap() + Ipv4Addr::from_str("255.255.255.255").unwrap(), )); - assert_eq!(i.collect::>(), vec![ - IpAddr::from_str("255.255.255.254").unwrap(), - IpAddr::from_str("255.255.255.255").unwrap(), - ]); + assert_eq!( + i.collect::>(), + vec![ + IpAddr::from_str("255.255.255.254").unwrap(), + IpAddr::from_str("255.255.255.255").unwrap(), + ] + ); let i = IpAddrRange::from(Ipv6AddrRange::new( Ipv6Addr::from_str("fd00::").unwrap(), Ipv6Addr::from_str("fd00::3").unwrap(), )); - assert_eq!(i.collect::>(), vec![ - IpAddr::from_str("fd00::").unwrap(), - IpAddr::from_str("fd00::1").unwrap(), - IpAddr::from_str("fd00::2").unwrap(), - IpAddr::from_str("fd00::3").unwrap(), - ]); + assert_eq!( + i.collect::>(), + vec![ + IpAddr::from_str("fd00::").unwrap(), + IpAddr::from_str("fd00::1").unwrap(), + IpAddr::from_str("fd00::2").unwrap(), + IpAddr::from_str("fd00::3").unwrap(), + ] + ); let mut v = i.collect::>(); v.reverse(); @@ -853,10 +876,13 @@ mod tests { Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), )); - assert_eq!(i.collect::>(), vec![ - IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(), - IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), - ]); + assert_eq!( + i.collect::>(), + vec![ + IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(), + IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), + ] + ); // #11 (infinite iterator when start and stop are 0) let zero4 = Ipv4Addr::from_str("0.0.0.0").unwrap(); @@ -873,7 +899,7 @@ mod tests { // Count let i = Ipv4AddrRange::new( Ipv4Addr::from_str("10.0.0.0").unwrap(), - Ipv4Addr::from_str("10.0.0.3").unwrap() + Ipv4Addr::from_str("10.0.0.3").unwrap(), ); assert_eq!(i.count(), 4); @@ -886,7 +912,7 @@ mod tests { // Size Hint let i = Ipv4AddrRange::new( Ipv4Addr::from_str("10.0.0.0").unwrap(), - Ipv4Addr::from_str("10.0.0.3").unwrap() + Ipv4Addr::from_str("10.0.0.3").unwrap(), ); assert_eq!(i.size_hint(), (4, Some(4))); @@ -906,27 +932,45 @@ mod tests { // Min, Max, Last let i = Ipv4AddrRange::new( Ipv4Addr::from_str("10.0.0.0").unwrap(), - Ipv4Addr::from_str("10.0.0.3").unwrap() + Ipv4Addr::from_str("10.0.0.3").unwrap(), + ); + assert_eq!( + Iterator::min(i), + Some(Ipv4Addr::from_str("10.0.0.0").unwrap()) + ); + assert_eq!( + Iterator::max(i), + Some(Ipv4Addr::from_str("10.0.0.3").unwrap()) ); - assert_eq!(Iterator::min(i), Some(Ipv4Addr::from_str("10.0.0.0").unwrap())); - assert_eq!(Iterator::max(i), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); assert_eq!(i.last(), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); let i = Ipv6AddrRange::new( Ipv6Addr::from_str("fd00::").unwrap(), Ipv6Addr::from_str("fd00::3").unwrap(), ); - assert_eq!(Iterator::min(i), Some(Ipv6Addr::from_str("fd00::").unwrap())); - assert_eq!(Iterator::max(i), Some(Ipv6Addr::from_str("fd00::3").unwrap())); + assert_eq!( + Iterator::min(i), + Some(Ipv6Addr::from_str("fd00::").unwrap()) + ); + assert_eq!( + Iterator::max(i), + Some(Ipv6Addr::from_str("fd00::3").unwrap()) + ); assert_eq!(i.last(), Some(Ipv6Addr::from_str("fd00::3").unwrap())); // Nth let i = Ipv4AddrRange::new( Ipv4Addr::from_str("10.0.0.0").unwrap(), - Ipv4Addr::from_str("10.0.0.3").unwrap() + Ipv4Addr::from_str("10.0.0.3").unwrap(), + ); + assert_eq!( + i.clone().nth(0), + Some(Ipv4Addr::from_str("10.0.0.0").unwrap()) + ); + assert_eq!( + i.clone().nth(3), + Some(Ipv4Addr::from_str("10.0.0.3").unwrap()) ); - assert_eq!(i.clone().nth(0), Some(Ipv4Addr::from_str("10.0.0.0").unwrap())); - assert_eq!(i.clone().nth(3), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); assert_eq!(i.clone().nth(4), None); assert_eq!(i.clone().nth(99), None); let mut i2 = i.clone(); @@ -941,8 +985,14 @@ mod tests { Ipv6Addr::from_str("fd00::").unwrap(), Ipv6Addr::from_str("fd00::3").unwrap(), ); - assert_eq!(i.clone().nth(0), Some(Ipv6Addr::from_str("fd00::").unwrap())); - assert_eq!(i.clone().nth(3), Some(Ipv6Addr::from_str("fd00::3").unwrap())); + assert_eq!( + i.clone().nth(0), + Some(Ipv6Addr::from_str("fd00::").unwrap()) + ); + assert_eq!( + i.clone().nth(3), + Some(Ipv6Addr::from_str("fd00::3").unwrap()) + ); assert_eq!(i.clone().nth(4), None); assert_eq!(i.clone().nth(99), None); let mut i2 = i.clone(); @@ -956,15 +1006,27 @@ mod tests { // Nth Back let i = Ipv4AddrRange::new( Ipv4Addr::from_str("10.0.0.0").unwrap(), - Ipv4Addr::from_str("10.0.0.3").unwrap() + Ipv4Addr::from_str("10.0.0.3").unwrap(), + ); + assert_eq!( + i.clone().nth_back(0), + Some(Ipv4Addr::from_str("10.0.0.3").unwrap()) + ); + assert_eq!( + i.clone().nth_back(3), + Some(Ipv4Addr::from_str("10.0.0.0").unwrap()) ); - assert_eq!(i.clone().nth_back(0), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); - assert_eq!(i.clone().nth_back(3), Some(Ipv4Addr::from_str("10.0.0.0").unwrap())); assert_eq!(i.clone().nth_back(4), None); assert_eq!(i.clone().nth_back(99), None); let mut i2 = i.clone(); - assert_eq!(i2.nth_back(1), Some(Ipv4Addr::from_str("10.0.0.2").unwrap())); - assert_eq!(i2.nth_back(1), Some(Ipv4Addr::from_str("10.0.0.0").unwrap())); + assert_eq!( + i2.nth_back(1), + Some(Ipv4Addr::from_str("10.0.0.2").unwrap()) + ); + assert_eq!( + i2.nth_back(1), + Some(Ipv4Addr::from_str("10.0.0.0").unwrap()) + ); assert_eq!(i2.nth_back(0), None); let mut i3 = i.clone(); assert_eq!(i3.nth_back(99), None); @@ -974,8 +1036,14 @@ mod tests { Ipv6Addr::from_str("fd00::").unwrap(), Ipv6Addr::from_str("fd00::3").unwrap(), ); - assert_eq!(i.clone().nth_back(0), Some(Ipv6Addr::from_str("fd00::3").unwrap())); - assert_eq!(i.clone().nth_back(3), Some(Ipv6Addr::from_str("fd00::").unwrap())); + assert_eq!( + i.clone().nth_back(0), + Some(Ipv6Addr::from_str("fd00::3").unwrap()) + ); + assert_eq!( + i.clone().nth_back(3), + Some(Ipv6Addr::from_str("fd00::").unwrap()) + ); assert_eq!(i.clone().nth_back(4), None); assert_eq!(i.clone().nth_back(99), None); let mut i2 = i.clone(); diff --git a/src/ipnet.rs b/src/ipnet.rs index cecb138..89f1fe7 100644 --- a/src/ipnet.rs +++ b/src/ipnet.rs @@ -1,20 +1,20 @@ use alloc::vec::Vec; -use core::cmp::{min, max}; -use core::cmp::Ordering::{Less, Equal}; +use core::cmp::Ordering::{Equal, Less}; +use core::cmp::{max, min}; use core::convert::From; +#[cfg(not(feature = "std"))] +use core::error::Error; use core::fmt; use core::iter::FusedIterator; -use core::option::Option::{Some, None}; #[cfg(not(feature = "std"))] -use core::error::Error; +use core::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use core::option::Option::{None, Some}; #[cfg(feature = "std")] use std::error::Error; -#[cfg(not(feature = "std"))] -use core::net::{IpAddr, Ipv4Addr, Ipv6Addr}; #[cfg(feature = "std")] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -use crate::ipext::{IpAdd, IpSub, IpStep, IpAddrRange, Ipv4AddrRange, Ipv6AddrRange}; +use crate::ipext::{IpAdd, IpAddrRange, IpStep, IpSub, Ipv4AddrRange, Ipv6AddrRange}; use crate::mask::{ip_mask_to_prefix, ipv4_mask_to_prefix, ipv6_mask_to_prefix}; /// An IP network address, either IPv4 or IPv6. @@ -142,7 +142,7 @@ impl IpNet { /// /// let net = IpNet::new(Ipv6Addr::LOCALHOST.into(), 48); /// assert!(net.is_ok()); - /// + /// /// let bad_prefix_len = IpNet::new(Ipv6Addr::LOCALHOST.into(), 129); /// assert_eq!(bad_prefix_len, Err(PrefixLenError)); /// ``` @@ -294,7 +294,7 @@ impl IpNet { IpNet::V6(ref a) => IpAddr::V6(a.hostmask()), } } - + /// Returns the network address. /// /// # Examples @@ -314,8 +314,8 @@ impl IpNet { IpNet::V4(ref a) => IpAddr::V4(a.network()), IpNet::V6(ref a) => IpAddr::V6(a.network()), } - } - + } + /// Returns the broadcast address. /// /// # Examples @@ -336,7 +336,7 @@ impl IpNet { IpNet::V6(ref a) => IpAddr::V6(a.broadcast()), } } - + /// Returns the `IpNet` that contains this one. /// /// # Examples @@ -365,7 +365,7 @@ impl IpNet { } } - /// Returns `true` if this network and the given network are + /// Returns `true` if this network and the given network are /// children of the same supernet. /// /// # Examples @@ -428,7 +428,7 @@ impl IpNet { IpNet::V6(ref a) => IpAddrRange::V6(a.hosts()), } } - + /// Returns an `Iterator` over the subnets of this network with the /// given prefix length. /// @@ -511,7 +511,10 @@ impl IpNet { /// assert!(!net4.contains(&ip6_no)); /// assert!(!net6.contains(&ip4_no)); /// ``` - pub fn contains(&self, other: T) -> bool where Self: Contains { + pub fn contains(&self, other: T) -> bool + where + Self: Contains, + { Contains::contains(self, other) } @@ -625,7 +628,10 @@ impl Ipv4Net { if prefix_len > 32 { return Err(PrefixLenError); } - Ok(Ipv4Net { addr: ip, prefix_len: prefix_len }) + Ok(Ipv4Net { + addr: ip, + prefix_len: prefix_len, + }) } /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix @@ -655,8 +661,14 @@ impl Ipv4Net { /// ``` #[inline] pub const fn new_assert(ip: Ipv4Addr, prefix_len: u8) -> Ipv4Net { - assert!(prefix_len <= 32, "PREFIX_LEN must be less then or equal to 32 for Ipv4Net"); - Ipv4Net { addr: ip, prefix_len: prefix_len } + assert!( + prefix_len <= 32, + "PREFIX_LEN must be less then or equal to 32 for Ipv4Net" + ); + Ipv4Net { + addr: ip, + prefix_len: prefix_len, + } } /// Creates a new IPv4 network address from an `Ipv4Addr` and netmask. @@ -712,7 +724,7 @@ impl Ipv4Net { pub const fn max_prefix_len(&self) -> u8 { 32 } - + /// Returns the network mask. /// /// # Examples @@ -729,7 +741,9 @@ impl Ipv4Net { } fn netmask_u32(&self) -> u32 { - u32::max_value().checked_shl(32 - self.prefix_len as u32).unwrap_or(0) + u32::max_value() + .checked_shl(32 - self.prefix_len as u32) + .unwrap_or(0) } /// Returns the host mask. @@ -748,7 +762,9 @@ impl Ipv4Net { } fn hostmask_u32(&self) -> u32 { - u32::max_value().checked_shr(self.prefix_len as u32).unwrap_or(0) + u32::max_value() + .checked_shr(self.prefix_len as u32) + .unwrap_or(0) } /// Returns the network address. @@ -796,10 +812,12 @@ impl Ipv4Net { /// assert_eq!(n3.supernet(), None); /// ``` pub fn supernet(&self) -> Option { - Ipv4Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok() + Ipv4Net::new(self.addr, self.prefix_len.wrapping_sub(1)) + .map(|n| n.trunc()) + .ok() } - /// Returns `true` if this network and the given network are + /// Returns `true` if this network and the given network are /// children of the same supernet. /// /// # Examples @@ -815,11 +833,11 @@ impl Ipv4Net { /// assert!(!n2.is_sibling(&n3)); /// ``` pub fn is_sibling(&self, other: &Ipv4Net) -> bool { - self.prefix_len > 0 && - self.prefix_len == other.prefix_len && - self.supernet().unwrap().contains(other) + self.prefix_len > 0 + && self.prefix_len == other.prefix_len + && self.supernet().unwrap().contains(other) } - + /// Return an `Iterator` over the host addresses in this network. /// /// If the prefix length is less than 31 both the network address @@ -847,12 +865,12 @@ impl Ipv4Net { pub fn hosts(&self) -> Ipv4AddrRange { let mut start = self.network(); let mut end = self.broadcast(); - + if self.prefix_len < 31 { start = start.saturating_add(1); end = end.saturating_sub(1); } - + Ipv4AddrRange::new(start, end) } @@ -890,7 +908,7 @@ impl Ipv4Net { if self.prefix_len > new_prefix_len || new_prefix_len > 32 { return Err(PrefixLenError); } - + Ok(Ipv4Subnets::new( self.network(), self.broadcast(), @@ -919,7 +937,10 @@ impl Ipv4Net { /// assert!(net.contains(&ip_yes)); /// assert!(!net.contains(&ip_no)); /// ``` - pub fn contains(&self, other: T) -> bool where Self: Contains { + pub fn contains(&self, other: T) -> bool + where + Self: Contains, + { Contains::contains(self, other) } @@ -953,7 +974,7 @@ impl Ipv4Net { let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect(); intervals = merge_intervals(intervals); let mut res: Vec = Vec::new(); - + for (start, mut end) in intervals { if end != core::u32::MAX { end = end.saturating_sub(1) @@ -988,11 +1009,14 @@ impl fmt::Display for Ipv4Net { impl From for Ipv4Net { fn from(addr: Ipv4Addr) -> Ipv4Net { - Ipv4Net { addr, prefix_len: 32 } + Ipv4Net { + addr, + prefix_len: 32, + } } } -impl Ipv6Net { +impl Ipv6Net { /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix /// length. /// @@ -1013,7 +1037,10 @@ impl Ipv6Net { if prefix_len > 128 { return Err(PrefixLenError); } - Ok(Ipv6Net { addr: ip, prefix_len: prefix_len }) + Ok(Ipv6Net { + addr: ip, + prefix_len: prefix_len, + }) } /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix @@ -1043,8 +1070,14 @@ impl Ipv6Net { /// ``` #[inline] pub const fn new_assert(ip: Ipv6Addr, prefix_len: u8) -> Ipv6Net { - assert!(prefix_len <= 128, "PREFIX_LEN must be less then or equal to 128 for Ipv6Net"); - Ipv6Net { addr: ip, prefix_len: prefix_len } + assert!( + prefix_len <= 128, + "PREFIX_LEN must be less then or equal to 128 for Ipv6Net" + ); + Ipv6Net { + addr: ip, + prefix_len: prefix_len, + } } /// Creates a new IPv6 network address from an `Ipv6Addr` and netmask. @@ -1082,7 +1115,7 @@ impl Ipv6Net { pub fn trunc(&self) -> Ipv6Net { Ipv6Net::new(self.network(), self.prefix_len).unwrap() } - + /// Returns the address. #[inline] pub const fn addr(&self) -> Ipv6Addr { @@ -1094,7 +1127,7 @@ impl Ipv6Net { pub const fn prefix_len(&self) -> u8 { self.prefix_len } - + /// Returns the maximum valid prefix length. #[inline] pub const fn max_prefix_len(&self) -> u8 { @@ -1117,7 +1150,9 @@ impl Ipv6Net { } fn netmask_u128(&self) -> u128 { - u128::max_value().checked_shl((128 - self.prefix_len) as u32).unwrap_or(u128::min_value()) + u128::max_value() + .checked_shl((128 - self.prefix_len) as u32) + .unwrap_or(u128::min_value()) } /// Returns the host mask. @@ -1136,7 +1171,9 @@ impl Ipv6Net { } fn hostmask_u128(&self) -> u128 { - u128::max_value().checked_shr(self.prefix_len as u32).unwrap_or(u128::min_value()) + u128::max_value() + .checked_shr(self.prefix_len as u32) + .unwrap_or(u128::min_value()) } /// Returns the network address. @@ -1153,7 +1190,7 @@ impl Ipv6Net { pub fn network(&self) -> Ipv6Addr { (u128::from(self.addr) & self.netmask_u128()).into() } - + /// Returns the last address. /// /// Technically there is no such thing as a broadcast address for @@ -1188,10 +1225,12 @@ impl Ipv6Net { /// assert_eq!(n3.supernet(), None); /// ``` pub fn supernet(&self) -> Option { - Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok() + Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)) + .map(|n| n.trunc()) + .ok() } - /// Returns `true` if this network and the given network are + /// Returns `true` if this network and the given network are /// children of the same supernet. /// /// # Examples @@ -1207,11 +1246,11 @@ impl Ipv6Net { /// assert!(!n2.is_sibling(&n3)); /// ``` pub fn is_sibling(&self, other: &Ipv6Net) -> bool { - self.prefix_len > 0 && - self.prefix_len == other.prefix_len && - self.supernet().unwrap().contains(other) + self.prefix_len > 0 + && self.prefix_len == other.prefix_len + && self.supernet().unwrap().contains(other) } - + /// Return an `Iterator` over the host addresses in this network. /// /// # Examples @@ -1266,7 +1305,7 @@ impl Ipv6Net { if self.prefix_len > new_prefix_len || new_prefix_len > 128 { return Err(PrefixLenError); } - + Ok(Ipv6Subnets::new( self.network(), self.broadcast(), @@ -1295,7 +1334,10 @@ impl Ipv6Net { /// assert!(net.contains(&ip_yes)); /// assert!(!net.contains(&ip_no)); /// ``` - pub fn contains(&self, other: T) -> bool where Self: Contains { + pub fn contains(&self, other: T) -> bool + where + Self: Contains, + { Contains::contains(self, other) } @@ -1364,7 +1406,10 @@ impl fmt::Display for Ipv6Net { impl From for Ipv6Net { fn from(addr: Ipv6Addr) -> Ipv6Net { - Ipv6Net { addr, prefix_len: 128 } + Ipv6Net { + addr, + prefix_len: 128, + } } } @@ -1469,7 +1514,7 @@ impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net { /// "10.0.0.239".parse().unwrap(), /// 26, /// )); -/// +/// /// assert_eq!(subnets.collect::>(), vec![ /// "10.0.0.0/26".parse().unwrap(), /// "10.0.0.64/26".parse().unwrap(), @@ -1483,7 +1528,7 @@ impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net { /// "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(), /// 26, /// )); -/// +/// /// assert_eq!(subnets.collect::>(), vec![ /// "fd00::/26".parse().unwrap(), /// "fd00:40::/26".parse().unwrap(), @@ -1516,7 +1561,7 @@ pub enum IpSubnets { /// "10.0.0.239".parse().unwrap(), /// 26, /// ); -/// +/// /// assert_eq!(subnets.collect::>(), vec![ /// "10.0.0.0/26".parse().unwrap(), /// "10.0.0.64/26".parse().unwrap(), @@ -1550,7 +1595,7 @@ pub struct Ipv4Subnets { /// "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(), /// 26, /// ); -/// +/// /// assert_eq!(subnets.collect::>(), vec![ /// "fd00::/26".parse().unwrap(), /// "fd00:40::/26".parse().unwrap(), @@ -1613,9 +1658,10 @@ fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4N let range = end.saturating_sub(start).saturating_add(1); if range == core::u32::MAX && min_prefix_len == 0 { Ipv4Net::new(start, min_prefix_len).unwrap() - } - else { - let range_bits = 32u32.saturating_sub(range.leading_zeros()).saturating_sub(1); + } else { + let range_bits = 32u32 + .saturating_sub(range.leading_zeros()) + .saturating_sub(1); let start_tz = u32::from(start).trailing_zeros(); let new_prefix_len = 32 - min(range_bits, start_tz); let next_prefix_len = max(new_prefix_len as u8, min_prefix_len); @@ -1627,10 +1673,11 @@ fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6N let range = end.saturating_sub(start).saturating_add(1); if range == core::u128::MAX && min_prefix_len == 0 { Ipv6Net::new(start, min_prefix_len).unwrap() - } - else { + } else { let range = end.saturating_sub(start).saturating_add(1); - let range_bits = 128u32.saturating_sub(range.leading_zeros()).saturating_sub(1); + let range_bits = 128u32 + .saturating_sub(range.leading_zeros()) + .saturating_sub(1); let start_tz = u128::from(start).trailing_zeros(); let new_prefix_len = 128 - min(range_bits, start_tz); let next_prefix_len = max(new_prefix_len as u8, min_prefix_len); @@ -1655,13 +1702,13 @@ impl Iterator for Ipv4Subnets { self.end.replace_zero(); } Some(next) - }, + } Some(Equal) => { let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len); self.start = next.broadcast().saturating_add(1); self.end.replace_zero(); Some(next) - }, + } _ => None, } } @@ -1684,13 +1731,13 @@ impl Iterator for Ipv6Subnets { self.end.replace_zero(); } Some(next) - }, + } Some(Equal) => { let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len); self.start = next.broadcast().saturating_add(1); self.end.replace_zero(); Some(next) - }, + } _ => None, } } @@ -1709,7 +1756,7 @@ fn merge_intervals(mut intervals: Vec<(T, T)>) -> Vec<(T, T)> { intervals.sort(); let mut res: Vec<(T, T)> = Vec::new(); let (mut start, mut end) = intervals[0]; - + let mut i = 1; let len = intervals.len(); while i < len { @@ -1717,8 +1764,7 @@ fn merge_intervals(mut intervals: Vec<(T, T)>) -> Vec<(T, T)> { if end >= next_start { start = min(start, next_start); end = max(end, next_end); - } - else { + } else { res.push((start, end)); start = next_start; end = next_end; @@ -1743,8 +1789,12 @@ mod tests { fn test_make_ipnet_vec() { assert_eq!( make_ipnet_vec![ - "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16", - "fd00::1/128", "fd00::2/127", "fd00::3/126", + "10.1.1.1/32", + "10.2.2.2/24", + "10.3.3.3/16", + "fd00::1/128", + "fd00::2/127", + "fd00::3/126", ], vec![ "10.1.1.1/32".parse().unwrap(), @@ -1760,26 +1810,28 @@ mod tests { #[test] fn test_merge_intervals() { let v = vec![ - (0, 1), (1, 2), (2, 3), - (11, 12), (13, 14), (10, 15), (11, 13), - (20, 25), (24, 29), - ]; - - let v_ok = vec![ - (0, 3), + (0, 1), + (1, 2), + (2, 3), + (11, 12), + (13, 14), (10, 15), - (20, 29), + (11, 13), + (20, 25), + (24, 29), ]; + let v_ok = vec![(0, 3), (10, 15), (20, 29)]; + let vv = vec![ - ([0, 1], [0, 2]), ([0, 2], [0, 3]), ([0, 0], [0, 1]), - ([10, 15], [11, 0]), ([10, 0], [10, 16]), + ([0, 1], [0, 2]), + ([0, 2], [0, 3]), + ([0, 0], [0, 1]), + ([10, 15], [11, 0]), + ([10, 0], [10, 16]), ]; - let vv_ok = vec![ - ([0, 0], [0, 3]), - ([10, 0], [11, 0]), - ]; + let vv_ok = vec![([0, 0], [0, 3]), ([10, 0], [11, 0])]; assert_eq!(merge_intervals(v), v_ok); assert_eq!(merge_intervals(vv), vv_ok); @@ -1823,88 +1875,81 @@ mod tests { make_ipv4_subnets_test!( test_ipv4_subnets_zero_zero, - "0.0.0.0", "0.0.0.0", 0, + "0.0.0.0", + "0.0.0.0", + 0, "0.0.0.0/32", ); make_ipv4_subnets_test!( test_ipv4_subnets_zero_max, - "0.0.0.0", "255.255.255.255", 0, + "0.0.0.0", + "255.255.255.255", + 0, "0.0.0.0/0", ); make_ipv4_subnets_test!( test_ipv4_subnets_max_max, - "255.255.255.255", "255.255.255.255", 0, + "255.255.255.255", + "255.255.255.255", + 0, "255.255.255.255/32", ); - - make_ipv4_subnets_test!( - test_ipv4_subnets_none, - "0.0.0.1", "0.0.0.0", 0, - ); - - make_ipv4_subnets_test!( - test_ipv4_subnets_one, - "0.0.0.0", "0.0.0.1", 0, - "0.0.0.0/31", - ); + + make_ipv4_subnets_test!(test_ipv4_subnets_none, "0.0.0.1", "0.0.0.0", 0,); + + make_ipv4_subnets_test!(test_ipv4_subnets_one, "0.0.0.0", "0.0.0.1", 0, "0.0.0.0/31",); make_ipv4_subnets_test!( test_ipv4_subnets_two, - "0.0.0.0", "0.0.0.2", 0, + "0.0.0.0", + "0.0.0.2", + 0, "0.0.0.0/31", "0.0.0.2/32", ); - + make_ipv4_subnets_test!( test_ipv4_subnets_taper, - "0.0.0.0", "0.0.0.10", 30, + "0.0.0.0", + "0.0.0.10", + 30, "0.0.0.0/30", "0.0.0.4/30", "0.0.0.8/31", "0.0.0.10/32", ); - - make_ipv6_subnets_test!( - test_ipv6_subnets_zero_zero, - "::", "::", 0, - "::/128", - ); + + make_ipv6_subnets_test!(test_ipv6_subnets_zero_zero, "::", "::", 0, "::/128",); make_ipv6_subnets_test!( test_ipv6_subnets_zero_max, - "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, + "::", + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", + 0, "::/0", ); make_ipv6_subnets_test!( test_ipv6_subnets_max_max, - "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", + 0, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", ); - - make_ipv6_subnets_test!( - test_ipv6_subnets_none, - "::1", "::", 0, - ); - - make_ipv6_subnets_test!( - test_ipv6_subnets_one, - "::", "::1", 0, - "::/127", - ); - make_ipv6_subnets_test!( - test_ipv6_subnets_two, - "::", "::2", 0, - "::/127", - "::2/128", - ); + make_ipv6_subnets_test!(test_ipv6_subnets_none, "::1", "::", 0,); + + make_ipv6_subnets_test!(test_ipv6_subnets_one, "::", "::1", 0, "::/127",); + + make_ipv6_subnets_test!(test_ipv6_subnets_two, "::", "::2", 0, "::/127", "::2/128",); make_ipv6_subnets_test!( test_ipv6_subnets_taper, - "::", "::a", 126, + "::", + "::a", + 126, "::/126", "::4/126", "::8/127", @@ -1914,11 +1959,19 @@ mod tests { #[test] fn test_aggregate() { let ip_nets = make_ipnet_vec![ - "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24", + "10.0.0.0/24", + "10.0.1.0/24", + "10.0.1.1/24", + "10.0.1.2/24", "10.0.2.0/24", - "10.1.0.0/24", "10.1.1.0/24", - "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24", - "fd00::/32", "fd00:1::/32", + "10.1.0.0/24", + "10.1.1.0/24", + "192.168.0.0/24", + "192.168.1.0/24", + "192.168.2.0/24", + "192.168.3.0/24", + "fd00::/32", + "fd00:1::/32", "fd00:2::/32", ]; @@ -1931,23 +1984,38 @@ mod tests { "fd00:2::/32", ]; - let ipv4_nets: Vec = ip_nets.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect(); - let ipv4_aggs: Vec = ip_aggs.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect(); - let ipv6_nets: Vec = ip_nets.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect(); - let ipv6_aggs: Vec = ip_aggs.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect(); + let ipv4_nets: Vec = ip_nets + .iter() + .filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }) + .collect(); + let ipv4_aggs: Vec = ip_aggs + .iter() + .filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }) + .collect(); + let ipv6_nets: Vec = ip_nets + .iter() + .filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }) + .collect(); + let ipv6_aggs: Vec = ip_aggs + .iter() + .filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }) + .collect(); assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs); assert_eq!(Ipv4Net::aggregate(&ipv4_nets), ipv4_aggs); assert_eq!(Ipv6Net::aggregate(&ipv6_nets), ipv6_aggs); } - + #[test] fn test_aggregate_issue44() { let nets: Vec = vec!["128.0.0.0/1".parse().unwrap()]; assert_eq!(Ipv4Net::aggregate(&nets), nets); let nets: Vec = vec!["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()]; - assert_eq!(Ipv4Net::aggregate(&nets), vec!["0.0.0.0/0".parse().unwrap()]); + assert_eq!( + Ipv4Net::aggregate(&nets), + vec!["0.0.0.0/0".parse().unwrap()] + ); let nets: Vec = vec!["8000::/1".parse().unwrap()]; assert_eq!(Ipv6Net::aggregate(&nets), nets); diff --git a/src/ipnet_schemars.rs b/src/ipnet_schemars.rs index 4e648f5..340e04d 100644 --- a/src/ipnet_schemars.rs +++ b/src/ipnet_schemars.rs @@ -1,17 +1,21 @@ +use crate::IpNet; use crate::Ipv4Net; use crate::Ipv6Net; -use crate::IpNet; use alloc::{ boxed::Box, - string::{ - String, - ToString - }, + string::{String, ToString}, vec, }; -use schemars::{JsonSchema, gen::SchemaGenerator, schema::{SubschemaValidation, Schema, SchemaObject, StringValidation, Metadata, SingleOrVec, InstanceType}}; +use schemars::{ + gen::SchemaGenerator, + schema::{ + InstanceType, Metadata, Schema, SchemaObject, SingleOrVec, StringValidation, + SubschemaValidation, + }, + JsonSchema, +}; impl JsonSchema for Ipv4Net { fn schema_name() -> String { @@ -37,7 +41,7 @@ impl JsonSchema for Ipv4Net { ..Default::default() })), ..Default::default() - }) + }) } } impl JsonSchema for Ipv6Net { @@ -60,11 +64,13 @@ impl JsonSchema for Ipv6Net { string: Some(Box::new(StringValidation { max_length: Some(43), min_length: None, - pattern: Some(r#"^[0-9A-Fa-f:\.]+\/(?:[0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$"#.to_string()), + pattern: Some( + r#"^[0-9A-Fa-f:\.]+\/(?:[0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$"#.to_string(), + ), ..Default::default() })), ..Default::default() - }) + }) } } impl JsonSchema for IpNet { @@ -83,13 +89,11 @@ impl JsonSchema for IpNet { ], ..Default::default() })), - subschemas: Some(Box::new( - SubschemaValidation { - one_of: Some(vec![Ipv4Net::json_schema(gen), Ipv6Net::json_schema(gen)]), - ..Default::default() - } - )), + subschemas: Some(Box::new(SubschemaValidation { + one_of: Some(vec![Ipv4Net::json_schema(gen), Ipv6Net::json_schema(gen)]), + ..Default::default() + })), ..Default::default() - }) + }) } } diff --git a/src/ipnet_serde.rs b/src/ipnet_serde.rs index cda12e3..ba5c2cb 100644 --- a/src/ipnet_serde.rs +++ b/src/ipnet_serde.rs @@ -2,15 +2,16 @@ use crate::{IpNet, Ipv4Net, Ipv6Net}; use core::fmt; #[cfg(not(feature = "std"))] use core::net::{Ipv4Addr, Ipv6Addr}; +use serde::de::{EnumAccess, Error, VariantAccess, Visitor}; +use serde::ser::SerializeTuple; +use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "std")] use std::net::{Ipv4Addr, Ipv6Addr}; -use serde::{self, Serialize, Deserialize, Serializer, Deserializer}; -use serde::ser::SerializeTuple; -use serde::de::{EnumAccess, Error, VariantAccess, Visitor}; impl Serialize for IpNet { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { if serializer.is_human_readable() { match *self { @@ -28,7 +29,8 @@ impl Serialize for IpNet { impl<'de> Deserialize<'de> for IpNet { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { if deserializer.is_human_readable() { struct IpNetVisitor; @@ -41,7 +43,8 @@ impl<'de> Deserialize<'de> for IpNet { } fn visit_str(self, s: &str) -> Result - where E: Error + where + E: Error, { s.parse().map_err(Error::custom) } @@ -65,7 +68,8 @@ impl<'de> Deserialize<'de> for IpNet { } fn visit_enum(self, data: A) -> Result - where A: EnumAccess<'de> + where + A: EnumAccess<'de>, { match data.variant()? { (IpNetKind::V4, v) => v.newtype_variant().map(IpNet::V4), @@ -81,7 +85,8 @@ impl<'de> Deserialize<'de> for IpNet { impl Serialize for Ipv4Net { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { if serializer.is_human_readable() { #[cfg(feature = "ser_as_str")] @@ -105,7 +110,8 @@ impl Serialize for Ipv4Net { impl<'de> Deserialize<'de> for Ipv4Net { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { if deserializer.is_human_readable() { struct IpAddrVisitor; @@ -118,7 +124,8 @@ impl<'de> Deserialize<'de> for Ipv4Net { } fn visit_str(self, s: &str) -> Result - where E: Error + where + E: Error, { s.parse().map_err(Error::custom) } @@ -127,14 +134,16 @@ impl<'de> Deserialize<'de> for Ipv4Net { deserializer.deserialize_str(IpAddrVisitor) } else { let b = <[u8; 5]>::deserialize(deserializer)?; - Ipv4Net::new(Ipv4Addr::new(b[0], b[1], b[2], b[3]), b[4]).map_err(serde::de::Error::custom) + Ipv4Net::new(Ipv4Addr::new(b[0], b[1], b[2], b[3]), b[4]) + .map_err(serde::de::Error::custom) } } } impl Serialize for Ipv6Net { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { if serializer.is_human_readable() { #[cfg(feature = "ser_as_str")] @@ -158,7 +167,8 @@ impl Serialize for Ipv6Net { impl<'de> Deserialize<'de> for Ipv6Net { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { if deserializer.is_human_readable() { struct IpAddrVisitor; @@ -171,7 +181,8 @@ impl<'de> Deserialize<'de> for Ipv6Net { } fn visit_str(self, s: &str) -> Result - where E: Error + where + E: Error, { s.parse().map_err(Error::custom) } @@ -180,12 +191,20 @@ impl<'de> Deserialize<'de> for Ipv6Net { deserializer.deserialize_str(IpAddrVisitor) } else { let b = <[u8; 17]>::deserialize(deserializer)?; - Ipv6Net::new(Ipv6Addr::new( - ((b[0] as u16) << 8) | b[1] as u16, ((b[2] as u16) << 8) | b[3] as u16, - ((b[4] as u16) << 8) | b[5] as u16, ((b[6] as u16) << 8) | b[7] as u16, - ((b[8] as u16) << 8) | b[9] as u16, ((b[10] as u16) << 8) | b[11] as u16, - ((b[12] as u16) << 8) | b[13] as u16, ((b[14] as u16) << 8) | b[15] as u16 - ), b[16]).map_err(Error::custom) + Ipv6Net::new( + Ipv6Addr::new( + ((b[0] as u16) << 8) | b[1] as u16, + ((b[2] as u16) << 8) | b[3] as u16, + ((b[4] as u16) << 8) | b[5] as u16, + ((b[6] as u16) << 8) | b[7] as u16, + ((b[8] as u16) << 8) | b[9] as u16, + ((b[10] as u16) << 8) | b[11] as u16, + ((b[12] as u16) << 8) | b[13] as u16, + ((b[14] as u16) << 8) | b[15] as u16, + ), + b[16], + ) + .map_err(Error::custom) } } } @@ -194,24 +213,30 @@ impl<'de> Deserialize<'de> for Ipv6Net { mod tests { extern crate serde_test; - use crate::{IpNet, Ipv4Net, Ipv6Net}; use self::serde_test::{assert_tokens, Configure, Token}; + use crate::{IpNet, Ipv4Net, Ipv6Net}; #[test] fn test_serialize_ipnet_v4() { let net_str = "10.1.1.0/24"; let net: IpNet = net_str.parse().unwrap(); assert_tokens(&net.readable(), &[Token::Str(net_str)]); - assert_tokens(&net.compact(), &[ - Token::NewtypeVariant { name: "IpNet", variant: "V4", }, - Token::Tuple { len: 5 }, - Token::U8(10), - Token::U8(1), - Token::U8(1), - Token::U8(0), - Token::U8(24), - Token::TupleEnd, - ]); + assert_tokens( + &net.compact(), + &[ + Token::NewtypeVariant { + name: "IpNet", + variant: "V4", + }, + Token::Tuple { len: 5 }, + Token::U8(10), + Token::U8(1), + Token::U8(1), + Token::U8(0), + Token::U8(24), + Token::TupleEnd, + ], + ); } #[test] @@ -219,30 +244,36 @@ mod tests { let net_str = "fd00::/32"; let net: IpNet = net_str.parse().unwrap(); assert_tokens(&net.readable(), &[Token::Str(net_str)]); - assert_tokens(&net.compact(), &[ - Token::NewtypeVariant { name: "IpNet", variant: "V6", }, - // This is too painful, but Token::Bytes() seems to be - // an array with a length, which is not what we serialize. - Token::Tuple { len: 17 }, - Token::U8(253u8), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(32), - Token::TupleEnd, - ]); + assert_tokens( + &net.compact(), + &[ + Token::NewtypeVariant { + name: "IpNet", + variant: "V6", + }, + // This is too painful, but Token::Bytes() seems to be + // an array with a length, which is not what we serialize. + Token::Tuple { len: 17 }, + Token::U8(253u8), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(32), + Token::TupleEnd, + ], + ); } #[test] @@ -250,15 +281,18 @@ mod tests { let net_str = "10.1.1.0/24"; let net: Ipv4Net = net_str.parse().unwrap(); assert_tokens(&net.readable(), &[Token::Str(net_str)]); - assert_tokens(&net.compact(), &[ - Token::Tuple { len: 5 }, - Token::U8(10), - Token::U8(1), - Token::U8(1), - Token::U8(0), - Token::U8(24), - Token::TupleEnd, - ]); + assert_tokens( + &net.compact(), + &[ + Token::Tuple { len: 5 }, + Token::U8(10), + Token::U8(1), + Token::U8(1), + Token::U8(0), + Token::U8(24), + Token::TupleEnd, + ], + ); } #[test] @@ -266,28 +300,31 @@ mod tests { let net_str = "fd00::/32"; let net: Ipv6Net = net_str.parse().unwrap(); assert_tokens(&net.readable(), &[Token::Str(net_str)]); - assert_tokens(&net.compact(), &[ - // This is too painful, but Token::Bytes() seems to be - // an array with a length, which is not what we serialize. - Token::Tuple { len: 17 }, - Token::U8(253u8), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(0), - Token::U8(32), - Token::TupleEnd, - ]); + assert_tokens( + &net.compact(), + &[ + // This is too painful, but Token::Bytes() seems to be + // an array with a length, which is not what we serialize. + Token::Tuple { len: 17 }, + Token::U8(253u8), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(0), + Token::U8(32), + Token::TupleEnd, + ], + ); } } diff --git a/src/lib.rs b/src/lib.rs index cb32370..109e9f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! [`IpAddr`], [`Ipv4Addr`], and [`Ipv6Addr`] types already provided in //! Rust's standard library and align to their design to stay //! consistent. -//! +//! //! The module also provides the [`IpSubnets`], [`Ipv4Subnets`], and //! [`Ipv6Subnets`] types for iterating over the subnets contained in //! an IP address range. The [`IpAddrRange`], [`Ipv4AddrRange`], and @@ -61,7 +61,7 @@ //! //! This library comes with support for [serde](https://serde.rs) but //! it's not enabled by default. Use the `serde` [feature] to enable. -//! +//! //! ```toml //! [dependencies] //! ipnet = { version = "2", features = ["serde"] } @@ -69,7 +69,7 @@ //! //! For human readable formats (e.g. JSON) the `IpNet`, `Ipv4Net`, and //! `Ipv6Net` types will serialize to their `Display` strings. -//! +//! //! For compact binary formats (e.g. Bincode) the `Ipv4Net` and //! `Ipv6Net` types will serialize to a string of 5 and 17 bytes that //! consist of the network address octects followed by the prefix @@ -86,21 +86,23 @@ extern crate std; #[cfg_attr(test, macro_use)] extern crate alloc; -#[cfg(feature = "serde")] -extern crate serde; #[cfg(feature = "schemars")] extern crate schemars; +#[cfg(feature = "serde")] +extern crate serde; -pub use self::ipext::{IpAdd, IpSub, IpBitAnd, IpBitOr, IpAddrRange, Ipv4AddrRange, Ipv6AddrRange}; -pub use self::ipnet::{IpNet, Ipv4Net, Ipv6Net, PrefixLenError, IpSubnets, Ipv4Subnets, Ipv6Subnets}; -pub use self::parser::AddrParseError; +pub use self::ipext::{IpAdd, IpAddrRange, IpBitAnd, IpBitOr, IpSub, Ipv4AddrRange, Ipv6AddrRange}; +pub use self::ipnet::{ + IpNet, IpSubnets, Ipv4Net, Ipv4Subnets, Ipv6Net, Ipv6Subnets, PrefixLenError, +}; pub use self::mask::{ip_mask_to_prefix, ipv4_mask_to_prefix, ipv6_mask_to_prefix}; +pub use self::parser::AddrParseError; mod ipext; mod ipnet; -mod parser; -mod mask; -#[cfg(feature = "serde")] -mod ipnet_serde; #[cfg(feature = "schemars")] mod ipnet_schemars; +#[cfg(feature = "serde")] +mod ipnet_serde; +mod mask; +mod parser; diff --git a/src/parser.rs b/src/parser.rs index d21fe60..e7abdd1 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4,15 +4,15 @@ //! is private. It is copied and extended here with methods for parsing //! IP network addresses. -use alloc::{str::FromStr, boxed::Box}; -use core::fmt; +use alloc::{boxed::Box, str::FromStr}; #[cfg(not(feature = "std"))] use core::error::Error; -#[cfg(feature = "std")] -use std::error::Error; +use core::fmt; #[cfg(not(feature = "std"))] use core::net::{Ipv4Addr, Ipv6Addr}; #[cfg(feature = "std")] +use std::error::Error; +#[cfg(feature = "std")] use std::net::{Ipv4Addr, Ipv6Addr}; use crate::ipnet::{IpNet, Ipv4Net, Ipv6Net}; @@ -36,7 +36,8 @@ impl<'a> Parser<'a> { } // Commit only if parser returns Some - fn read_atomically(&mut self, cb: F) -> Option where + fn read_atomically(&mut self, cb: F) -> Option + where F: FnOnce(&mut Parser) -> Option, { let pos = self.pos; @@ -48,20 +49,27 @@ impl<'a> Parser<'a> { } // Commit only if parser read till EOF - fn read_till_eof(&mut self, cb: F) -> Option where + fn read_till_eof(&mut self, cb: F) -> Option + where F: FnOnce(&mut Parser) -> Option, { - self.read_atomically(move |p| { - match cb(p) { - Some(x) => if p.is_eof() {Some(x)} else {None}, - None => None, + self.read_atomically(move |p| match cb(p) { + Some(x) => { + if p.is_eof() { + Some(x) + } else { + None + } } + None => None, }) } // Return result of first successful parser - fn read_or(&mut self, parsers: &mut [Box Option + 'static>]) - -> Option { + fn read_or( + &mut self, + parsers: &mut [Box Option + 'static>], + ) -> Option { for pf in parsers { if let Some(r) = self.read_atomically(|p: &mut Parser| pf(p)) { return Some(r); @@ -71,11 +79,8 @@ impl<'a> Parser<'a> { } // Apply 3 parsers sequentially - fn read_seq_3(&mut self, - pa: PA, - pb: PB, - pc: PC) - -> Option<(A, B, C)> where + fn read_seq_3(&mut self, pa: PA, pb: PB, pc: PC) -> Option<(A, B, C)> + where PA: FnOnce(&mut Parser) -> Option, PB: FnOnce(&mut Parser) -> Option, PC: FnOnce(&mut Parser) -> Option, @@ -86,7 +91,7 @@ impl<'a> Parser<'a> { let c = if b.is_some() { pc(p) } else { None }; match (a, b, c) { (Some(a), Some(b), Some(c)) => Some((a, b, c)), - _ => None + _ => None, } }) } @@ -104,11 +109,9 @@ impl<'a> Parser<'a> { // Return char and advance iff next char is equal to requested fn read_given_char(&mut self, c: char) -> Option { - self.read_atomically(|p| { - match p.read_char() { - Some(next) if next == c => Some(next), - _ => None, - } + self.read_atomically(|p| match p.read_char() { + Some(next) if next == c => Some(next), + _ => None, }) } @@ -128,9 +131,7 @@ impl<'a> Parser<'a> { } } - self.read_atomically(|p| { - p.read_char().and_then(|c| parse_digit(c, radix)) - }) + self.read_atomically(|p| p.read_char().and_then(|c| parse_digit(c, radix))) } fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option { @@ -142,14 +143,14 @@ impl<'a> Parser<'a> { r = r * (radix as u32) + (d as u32); digit_count += 1; if digit_count > max_digits || r >= upto { - return None + return None; } } None => { if digit_count == 0 { - return None + return None; } else { - return Some(r) + return Some(r); } } }; @@ -189,12 +190,11 @@ impl<'a> Parser<'a> { assert!(head.len() + tail.len() <= 8); let mut gs = [0; 8]; gs[..head.len()].copy_from_slice(head); - gs[(8 - tail.len()) .. 8].copy_from_slice(tail); + gs[(8 - tail.len())..8].copy_from_slice(tail); Ipv6Addr::new(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7]) } - fn read_groups(p: &mut Parser, groups: &mut [u16; 8], limit: usize) - -> (usize, bool) { + fn read_groups(p: &mut Parser, groups: &mut [u16; 8], limit: usize) -> (usize, bool) { let mut i = 0; while i < limit { if i < limit - 1 { @@ -222,7 +222,7 @@ impl<'a> Parser<'a> { }); match group { Some(g) => groups[i] = g, - None => return (i, false) + None => return (i, false), } i += 1; } @@ -234,13 +234,13 @@ impl<'a> Parser<'a> { if head_size == 8 { return Some(Ipv6Addr::new( - head[0], head[1], head[2], head[3], - head[4], head[5], head[6], head[7])) + head[0], head[1], head[2], head[3], head[4], head[5], head[6], head[7], + )); } // IPv4 part is not allowed before `::` if head_ipv4 { - return None + return None; } // read `::` if previous code parsed less than 8 groups @@ -250,22 +250,23 @@ impl<'a> Parser<'a> { let mut tail = [0; 8]; let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size); - Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size])) + Some(ipv6_addr_from_head_tail( + &head[..head_size], + &tail[..tail_size], + )) } fn read_ipv6_addr(&mut self) -> Option { self.read_atomically(|p| p.read_ipv6_addr_impl()) } - + /* Additions for IpNet below. */ // Read IPv4 network fn read_ipv4_net(&mut self) -> Option { let ip_addr = |p: &mut Parser| p.read_ipv4_addr(); let slash = |p: &mut Parser| p.read_given_char('/'); - let prefix_len = |p: &mut Parser| { - p.read_number(10, 2, 33).map(|n| n as u8) - }; + let prefix_len = |p: &mut Parser| p.read_number(10, 2, 33).map(|n| n as u8); self.read_seq_3(ip_addr, slash, prefix_len).map(|t| { let (ip, _, prefix_len): (Ipv4Addr, char, u8) = t; @@ -277,9 +278,7 @@ impl<'a> Parser<'a> { fn read_ipv6_net(&mut self) -> Option { let ip_addr = |p: &mut Parser| p.read_ipv6_addr(); let slash = |p: &mut Parser| p.read_given_char('/'); - let prefix_len = |p: &mut Parser| { - p.read_number(10, 3, 129).map(|n| n as u8) - }; + let prefix_len = |p: &mut Parser| p.read_number(10, 3, 129).map(|n| n as u8); self.read_seq_3(ip_addr, slash, prefix_len).map(|t| { let (ip, _, prefix_len): (Ipv6Addr, char, u8) = t; @@ -303,7 +302,7 @@ impl FromStr for IpNet { fn from_str(s: &str) -> Result { match Parser::new(s).read_till_eof(|p| p.read_ip_net()) { Some(s) => Ok(s), - None => Err(AddrParseError(())) + None => Err(AddrParseError(())), } } } @@ -313,7 +312,7 @@ impl FromStr for Ipv4Net { fn from_str(s: &str) -> Result { match Parser::new(s).read_till_eof(|p| p.read_ipv4_net()) { Some(s) => Ok(s), - None => Err(AddrParseError(())) + None => Err(AddrParseError(())), } } } @@ -323,7 +322,7 @@ impl FromStr for Ipv6Net { fn from_str(s: &str) -> Result { match Parser::new(s).read_till_eof(|p| p.read_ipv6_net()) { Some(s) => Ok(s), - None => Err(AddrParseError(())) + None => Err(AddrParseError(())), } } }