RPM build fix (reverted CI changes which will need to be un-reverted or made conditional) and vendor Rust dependencies to make builds much faster in any CI system.

This commit is contained in:
Adam Ierymenko
2022-06-08 07:32:16 -04:00
parent 373ca30269
commit d5ca4e5f52
12611 changed files with 2898014 additions and 284 deletions

966
zeroidc/vendor/ipnet/src/ipext.rs vendored Normal file
View File

@@ -0,0 +1,966 @@
//! Extensions to the standard IP address types for common operations.
//!
//! The [`IpAdd`], [`IpSub`], [`IpBitAnd`], [`IpBitOr`] traits extend
//! the `Ipv4Addr` and `Ipv6Addr` types with methods to perform these
//! operations.
use std::cmp::Ordering::{Less, Equal};
use std::iter::{FusedIterator, DoubleEndedIterator};
use std::mem;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
/// Provides a `saturating_add()` method for `Ipv4Addr` and `Ipv6Addr`.
///
/// Adding an integer to an IP address returns the modified IP address.
/// A `u32` may added to an IPv4 address and a `u128` may be added to
/// an IPv6 address.
///
/// # Examples
///
/// ```
/// use std::net::{Ipv4Addr, Ipv6Addr};
/// use ipnet::IpAdd;
///
/// let ip0: Ipv4Addr = "192.168.0.0".parse().unwrap();
/// let ip1: Ipv4Addr = "192.168.0.5".parse().unwrap();
/// let ip2: Ipv4Addr = "255.255.255.254".parse().unwrap();
/// let max: Ipv4Addr = "255.255.255.255".parse().unwrap();
///
/// assert_eq!(ip0.saturating_add(5), ip1);
/// assert_eq!(ip2.saturating_add(1), max);
/// assert_eq!(ip2.saturating_add(5), max);
///
/// let ip0: Ipv6Addr = "fd00::".parse().unwrap();
/// let ip1: Ipv6Addr = "fd00::5".parse().unwrap();
/// let ip2: Ipv6Addr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe".parse().unwrap();
/// let max: Ipv6Addr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap();
///
/// assert_eq!(ip0.saturating_add(5), ip1);
/// assert_eq!(ip2.saturating_add(1), max);
/// assert_eq!(ip2.saturating_add(5), max);
/// ```
pub trait IpAdd<RHS = Self> {
type Output;
fn saturating_add(self, rhs: RHS) -> Self::Output;
}
/// Provides a `saturating_sub()` method for `Ipv4Addr` and `Ipv6Addr`.
///
/// Subtracting an integer from an IP address returns the modified IP
/// address. A `u32` may be subtracted from an IPv4 address and a `u128`
/// may be subtracted from an IPv6 address.
///
/// Subtracting an IP address from another IP address of the same type
/// returns an integer of the appropriate width. A `u32` for IPv4 and a
/// `u128` for IPv6. Subtracting IP addresses is useful for getting
/// the range between two IP addresses.
///
/// # Examples
///
/// ```
/// use std::net::{Ipv4Addr, Ipv6Addr};
/// use ipnet::IpSub;
///
/// let min: Ipv4Addr = "0.0.0.0".parse().unwrap();
/// let ip1: Ipv4Addr = "192.168.1.5".parse().unwrap();
/// let ip2: Ipv4Addr = "192.168.1.100".parse().unwrap();
///
/// assert_eq!(min.saturating_sub(ip1), 0);
/// 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();
///
/// assert_eq!(min.saturating_sub(ip1), 0);
/// assert_eq!(ip2.saturating_sub(ip1), 95);
/// assert_eq!(min.saturating_sub(5u128), min);
/// assert_eq!(ip2.saturating_sub(95u128), ip1);
/// ```
pub trait IpSub<RHS = Self> {
type Output;
fn saturating_sub(self, rhs: RHS) -> Self::Output;
}
/// Provides a `bitand()` method for `Ipv4Addr` and `Ipv6Addr`.
///
/// # Examples
///
/// ```
/// use std::net::{Ipv4Addr, Ipv6Addr};
/// use ipnet::IpBitAnd;
///
/// let ip: Ipv4Addr = "192.168.1.1".parse().unwrap();
/// let mask: Ipv4Addr = "255.255.0.0".parse().unwrap();
/// let res: Ipv4Addr = "192.168.0.0".parse().unwrap();
///
/// 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();
///
/// assert_eq!(ip.bitand(mask), res);
/// assert_eq!(ip.bitand(0xffff_0000_0000_0000_0000_0000_0000_0000u128), res);
/// ```
pub trait IpBitAnd<RHS = Self> {
type Output;
fn bitand(self, rhs: RHS) -> Self::Output;
}
/// Provides a `bitor()` method for `Ipv4Addr` and `Ipv6Addr`.
///
/// # Examples
///
/// ```
/// use std::net::{Ipv4Addr, Ipv6Addr};
/// use ipnet::IpBitOr;
///
/// let ip: Ipv4Addr = "10.1.1.1".parse().unwrap();
/// let mask: Ipv4Addr = "0.0.0.255".parse().unwrap();
/// let res: Ipv4Addr = "10.1.1.255".parse().unwrap();
///
/// 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();
///
/// assert_eq!(ip.bitor(mask), res);
/// assert_eq!(ip.bitor(u128::from(0xffffffffu32)), res);
/// ```
pub trait IpBitOr<RHS = Self> {
type Output;
fn bitor(self, rhs: RHS) -> Self::Output;
}
macro_rules! ip_add_impl {
($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => (
impl IpAdd<$rhs> for $lhs {
type Output = $output;
fn saturating_add(self, rhs: $rhs) -> $output {
let lhs: $inner = self.into();
let rhs: $inner = rhs.into();
(lhs.saturating_add(rhs.into())).into()
}
}
)
}
macro_rules! ip_sub_impl {
($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => (
impl IpSub<$rhs> for $lhs {
type Output = $output;
fn saturating_sub(self, rhs: $rhs) -> $output {
let lhs: $inner = self.into();
let rhs: $inner = rhs.into();
(lhs.saturating_sub(rhs.into())).into()
}
}
)
}
ip_add_impl!(Ipv4Addr, u32, Ipv4Addr, u32);
ip_add_impl!(Ipv6Addr, u128, Ipv6Addr, u128);
ip_sub_impl!(Ipv4Addr, Ipv4Addr, u32, u32);
ip_sub_impl!(Ipv4Addr, u32, Ipv4Addr, u32);
ip_sub_impl!(Ipv6Addr, Ipv6Addr, u128, u128);
ip_sub_impl!(Ipv6Addr, u128, Ipv6Addr, u128);
macro_rules! ip_bitops_impl {
($(($lhs:ty, $rhs:ty, $t:ty),)*) => {
$(
impl IpBitAnd<$rhs> for $lhs {
type Output = $lhs;
fn bitand(self, rhs: $rhs) -> $lhs {
let lhs: $t = self.into();
let rhs: $t = rhs.into();
(lhs & rhs).into()
}
}
impl IpBitOr<$rhs> for $lhs {
type Output = $lhs;
fn bitor(self, rhs: $rhs) -> $lhs {
let lhs: $t = self.into();
let rhs: $t = rhs.into();
(lhs | rhs).into()
}
}
)*
}
}
ip_bitops_impl! {
(Ipv4Addr, Ipv4Addr, u32),
(Ipv4Addr, u32, u32),
(Ipv6Addr, Ipv6Addr, u128),
(Ipv6Addr, u128, u128),
}
// A barebones copy of the current unstable Step trait used by the
// IpAddrRange, Ipv4AddrRange, and Ipv6AddrRange types below, and the
// Subnets types in ipnet.
pub trait IpStep {
fn replace_one(&mut self) -> Self;
fn replace_zero(&mut self) -> Self;
fn add_one(&self) -> Self;
fn sub_one(&self) -> Self;
}
impl IpStep for Ipv4Addr {
fn replace_one(&mut self) -> Self {
mem::replace(self, Ipv4Addr::new(0, 0, 0, 1))
}
fn replace_zero(&mut self) -> Self {
mem::replace(self, Ipv4Addr::new(0, 0, 0, 0))
}
fn add_one(&self) -> Self {
self.saturating_add(1)
}
fn sub_one(&self) -> Self {
self.saturating_sub(1)
}
}
impl IpStep for Ipv6Addr {
fn replace_one(&mut self) -> Self {
mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
}
fn replace_zero(&mut self) -> Self {
mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0))
}
fn add_one(&self) -> Self {
self.saturating_add(1)
}
fn sub_one(&self) -> Self {
self.saturating_sub(1)
}
}
/// An `Iterator` over a range of IP addresses, either IPv4 or IPv6.
///
/// # Examples
///
/// ```
/// use std::net::IpAddr;
/// use ipnet::{IpAddrRange, Ipv4AddrRange, Ipv6AddrRange};
///
/// let hosts = IpAddrRange::from(Ipv4AddrRange::new(
/// "10.0.0.0".parse().unwrap(),
/// "10.0.0.3".parse().unwrap(),
/// ));
///
/// assert_eq!(hosts.collect::<Vec<IpAddr>>(), vec![
/// "10.0.0.0".parse::<IpAddr>().unwrap(),
/// "10.0.0.1".parse().unwrap(),
/// "10.0.0.2".parse().unwrap(),
/// "10.0.0.3".parse().unwrap(),
/// ]);
///
/// let hosts = IpAddrRange::from(Ipv6AddrRange::new(
/// "fd00::".parse().unwrap(),
/// "fd00::3".parse().unwrap(),
/// ));
///
/// assert_eq!(hosts.collect::<Vec<IpAddr>>(), vec![
/// "fd00::0".parse::<IpAddr>().unwrap(),
/// "fd00::1".parse().unwrap(),
/// "fd00::2".parse().unwrap(),
/// "fd00::3".parse().unwrap(),
/// ]);
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum IpAddrRange {
V4(Ipv4AddrRange),
V6(Ipv6AddrRange),
}
/// An `Iterator` over a range of IPv4 addresses.
///
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnet::Ipv4AddrRange;
///
/// let hosts = Ipv4AddrRange::new(
/// "10.0.0.0".parse().unwrap(),
/// "10.0.0.3".parse().unwrap(),
/// );
///
/// assert_eq!(hosts.collect::<Vec<Ipv4Addr>>(), vec![
/// "10.0.0.0".parse::<Ipv4Addr>().unwrap(),
/// "10.0.0.1".parse().unwrap(),
/// "10.0.0.2".parse().unwrap(),
/// "10.0.0.3".parse().unwrap(),
/// ]);
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct Ipv4AddrRange {
start: Ipv4Addr,
end: Ipv4Addr,
}
/// An `Iterator` over a range of IPv6 addresses.
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
/// use ipnet::Ipv6AddrRange;
///
/// let hosts = Ipv6AddrRange::new(
/// "fd00::".parse().unwrap(),
/// "fd00::3".parse().unwrap(),
/// );
///
/// assert_eq!(hosts.collect::<Vec<Ipv6Addr>>(), vec![
/// "fd00::".parse::<Ipv6Addr>().unwrap(),
/// "fd00::1".parse().unwrap(),
/// "fd00::2".parse().unwrap(),
/// "fd00::3".parse().unwrap(),
/// ]);
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct Ipv6AddrRange {
start: Ipv6Addr,
end: Ipv6Addr,
}
impl From<Ipv4AddrRange> for IpAddrRange {
fn from(i: Ipv4AddrRange) -> IpAddrRange {
IpAddrRange::V4(i)
}
}
impl From<Ipv6AddrRange> for IpAddrRange {
fn from(i: Ipv6AddrRange) -> IpAddrRange {
IpAddrRange::V6(i)
}
}
impl Ipv4AddrRange {
pub fn new(start: Ipv4Addr, end: Ipv4Addr) -> Self {
Ipv4AddrRange {
start: start,
end: end,
}
}
/// Counts the number of Ipv4Addr in this range.
/// This method will never overflow or panic.
fn count_u64(&self) -> u64 {
match self.start.partial_cmp(&self.end) {
Some(Less) => {
let count: u32 = self.end.saturating_sub(self.start);
let count = count as u64 + 1; // Never overflows
count
},
Some(Equal) => 1,
_ => 0,
}
}
}
impl Ipv6AddrRange {
pub fn new(start: Ipv6Addr, end: Ipv6Addr) -> Self {
Ipv6AddrRange {
start: start,
end: end,
}
}
/// Counts the number of Ipv6Addr in this range.
/// This method may overflow or panic if start
/// is 0 and end is u128::MAX
fn count_u128(&self) -> u128 {
match self.start.partial_cmp(&self.end) {
Some(Less) => {
let count = self.end.saturating_sub(self.start);
// May overflow or panic
count + 1
},
Some(Equal) => 1,
_ => 0,
}
}
/// 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)
}
}
impl Iterator for IpAddrRange {
type Item = IpAddr;
fn next(&mut self) -> Option<Self::Item> {
match *self {
IpAddrRange::V4(ref mut a) => a.next().map(IpAddr::V4),
IpAddrRange::V6(ref mut a) => a.next().map(IpAddr::V6),
}
}
fn count(self) -> usize {
match self {
IpAddrRange::V4(a) => a.count(),
IpAddrRange::V6(a) => a.count(),
}
}
fn last(self) -> Option<Self::Item> {
match self {
IpAddrRange::V4(a) => a.last().map(IpAddr::V4),
IpAddrRange::V6(a) => a.last().map(IpAddr::V6),
}
}
fn max(self) -> Option<Self::Item> {
match self {
IpAddrRange::V4(a) => Iterator::max(a).map(IpAddr::V4),
IpAddrRange::V6(a) => Iterator::max(a).map(IpAddr::V6),
}
}
fn min(self) -> Option<Self::Item> {
match self {
IpAddrRange::V4(a) => Iterator::min(a).map(IpAddr::V4),
IpAddrRange::V6(a) => Iterator::min(a).map(IpAddr::V6),
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
match *self {
IpAddrRange::V4(ref mut a) => a.nth(n).map(IpAddr::V4),
IpAddrRange::V6(ref mut a) => a.nth(n).map(IpAddr::V6),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match *self {
IpAddrRange::V4(ref a) => a.size_hint(),
IpAddrRange::V6(ref a) => a.size_hint(),
}
}
}
impl Iterator for Ipv4AddrRange {
type Item = Ipv4Addr;
fn next(&mut self) -> Option<Self::Item> {
match self.start.partial_cmp(&self.end) {
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,
}
}
#[allow(const_err)]
#[allow(arithmetic_overflow)]
fn count(self) -> usize {
match self.start.partial_cmp(&self.end) {
Some(Less) => {
// Adding one here might overflow u32.
// Instead, wait until after converted to usize
let count: u32 = self.end.saturating_sub(self.start);
// usize might only be 16 bits,
// so need to explicitly check for overflow.
// 'usize::MAX as u32' is okay here - if usize is 64 bits,
// value truncates to u32::MAX
if count <= std::usize::MAX as u32 {
count as usize + 1
// count overflows usize
} else {
// emulate standard overflow/panic behavior
std::usize::MAX + 2 + count as usize
}
},
Some(Equal) => 1,
_ => 0
}
}
fn last(self) -> Option<Self::Item> {
match self.start.partial_cmp(&self.end) {
Some(Less) | Some(Equal) => Some(self.end),
_ => None,
}
}
fn max(self) -> Option<Self::Item> {
self.last()
}
fn min(self) -> Option<Self::Item> {
match self.start.partial_cmp(&self.end) {
Some(Less) | Some(Equal) => Some(self.start),
_ => None
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let n = n as u64;
let count = self.count_u64();
if n >= count {
self.end.replace_zero();
self.start.replace_one();
None
} else if n == count - 1 {
self.start.replace_one();
Some(self.end.replace_zero())
} else {
let nth = self.start.saturating_add(n as u32);
self.start = nth.add_one();
Some(nth)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let count = self.count_u64();
if count > std::usize::MAX as u64 {
(std::usize::MAX, None)
} else {
let count = count as usize;
(count, Some(count))
}
}
}
impl Iterator for Ipv6AddrRange {
type Item = Ipv6Addr;
fn next(&mut self) -> Option<Self::Item> {
match self.start.partial_cmp(&self.end) {
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,
}
}
#[allow(const_err)]
#[allow(arithmetic_overflow)]
fn count(self) -> usize {
let count = self.count_u128();
// count fits in usize
if count <= std::usize::MAX as u128 {
count as usize
// count does not fit in usize
} else {
// emulate standard overflow/panic behavior
std::usize::MAX + 1 + count as usize
}
}
fn last(self) -> Option<Self::Item> {
match self.start.partial_cmp(&self.end) {
Some(Less) | Some(Equal) => Some(self.end),
_ => None,
}
}
fn max(self) -> Option<Self::Item> {
self.last()
}
fn min(self) -> Option<Self::Item> {
match self.start.partial_cmp(&self.end) {
Some(Less) | Some(Equal) => Some(self.start),
_ => None
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let n = n as u128;
if self.can_count_u128() {
let count = self.count_u128();
if n >= count {
self.end.replace_zero();
self.start.replace_one();
None
} else if n == count - 1 {
self.start.replace_one();
Some(self.end.replace_zero())
} else {
let nth = self.start.saturating_add(n);
self.start = nth.add_one();
Some(nth)
}
// count overflows u128; n is 64-bits at most.
// therefore, n can never exceed count
} else {
let nth = self.start.saturating_add(n);
self.start = nth.add_one();
Some(nth)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.can_count_u128() {
let count = self.count_u128();
if count > std::usize::MAX as u128 {
(std::usize::MAX, None)
} else {
let count = count as usize;
(count, Some(count))
}
} else {
(std::usize::MAX, None)
}
}
}
impl DoubleEndedIterator for IpAddrRange {
fn next_back(&mut self) -> Option<Self::Item> {
match *self {
IpAddrRange::V4(ref mut a) => a.next_back().map(IpAddr::V4),
IpAddrRange::V6(ref mut a) => a.next_back().map(IpAddr::V6),
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
match *self {
IpAddrRange::V4(ref mut a) => a.nth_back(n).map(IpAddr::V4),
IpAddrRange::V6(ref mut a) => a.nth_back(n).map(IpAddr::V6),
}
}
}
impl DoubleEndedIterator for Ipv4AddrRange {
fn next_back(&mut self) -> Option<Self::Item> {
match self.start.partial_cmp(&self.end) {
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
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let n = n as u64;
let count = self.count_u64();
if n >= count {
self.end.replace_zero();
self.start.replace_one();
None
} else if n == count - 1 {
self.end.replace_zero();
Some(self.start.replace_one())
} else {
let nth_back = self.end.saturating_sub(n as u32);
self.end = nth_back.sub_one();
Some(nth_back)
}
}
}
impl DoubleEndedIterator for Ipv6AddrRange {
fn next_back(&mut self) -> Option<Self::Item> {
match self.start.partial_cmp(&self.end) {
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
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let n = n as u128;
if self.can_count_u128() {
let count = self.count_u128();
if n >= count {
self.end.replace_zero();
self.start.replace_one();
None
}
else if n == count - 1 {
self.end.replace_zero();
Some(self.start.replace_one())
} else {
let nth_back = self.end.saturating_sub(n);
self.end = nth_back.sub_one();
Some(nth_back)
}
// count overflows u128; n is 64-bits at most.
// therefore, n can never exceed count
} else {
let nth_back = self.end.saturating_sub(n);
self.end = nth_back.sub_one();
Some(nth_back)
}
}
}
impl FusedIterator for IpAddrRange {}
impl FusedIterator for Ipv4AddrRange {}
impl FusedIterator for Ipv6AddrRange {}
#[cfg(test)]
mod tests {
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
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()
);
assert_eq!(i.collect::<Vec<Ipv4Addr>>(), 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::<Vec<_>>();
v.reverse();
assert_eq!(v, i.rev().collect::<Vec<_>>());
let i = Ipv4AddrRange::new(
Ipv4Addr::from_str("255.255.255.254").unwrap(),
Ipv4Addr::from_str("255.255.255.255").unwrap()
);
assert_eq!(i.collect::<Vec<Ipv4Addr>>(), 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>>(), 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::<Vec<_>>();
v.reverse();
assert_eq!(v, i.rev().collect::<Vec<_>>());
let i = Ipv6AddrRange::new(
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>>(), 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>>(), 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::<Vec<_>>();
v.reverse();
assert_eq!(v, i.rev().collect::<Vec<_>>());
let i = IpAddrRange::from(Ipv4AddrRange::new(
Ipv4Addr::from_str("255.255.255.254").unwrap(),
Ipv4Addr::from_str("255.255.255.255").unwrap()
));
assert_eq!(i.collect::<Vec<IpAddr>>(), 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>>(), 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::<Vec<_>>();
v.reverse();
assert_eq!(v, i.rev().collect::<Vec<_>>());
let i = IpAddrRange::from(Ipv6AddrRange::new(
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<IpAddr>>(), 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();
let zero6 = Ipv6Addr::from_str("::").unwrap();
let mut i = Ipv4AddrRange::new(zero4, zero4);
assert_eq!(Some(zero4), i.next());
assert_eq!(None, i.next());
let mut i = Ipv6AddrRange::new(zero6, zero6);
assert_eq!(Some(zero6), i.next());
assert_eq!(None, i.next());
// Count
let i = Ipv4AddrRange::new(
Ipv4Addr::from_str("10.0.0.0").unwrap(),
Ipv4Addr::from_str("10.0.0.3").unwrap()
);
assert_eq!(i.count(), 4);
let i = Ipv6AddrRange::new(
Ipv6Addr::from_str("fd00::").unwrap(),
Ipv6Addr::from_str("fd00::3").unwrap(),
);
assert_eq!(i.count(), 4);
// Size Hint
let i = Ipv4AddrRange::new(
Ipv4Addr::from_str("10.0.0.0").unwrap(),
Ipv4Addr::from_str("10.0.0.3").unwrap()
);
assert_eq!(i.size_hint(), (4, Some(4)));
let i = Ipv6AddrRange::new(
Ipv6Addr::from_str("fd00::").unwrap(),
Ipv6Addr::from_str("fd00::3").unwrap(),
);
assert_eq!(i.size_hint(), (4, Some(4)));
// Size Hint: a range where size clearly overflows usize
let i = Ipv6AddrRange::new(
Ipv6Addr::from_str("::").unwrap(),
Ipv6Addr::from_str("8000::").unwrap(),
);
assert_eq!(i.size_hint(), (std::usize::MAX, None));
// Min, Max, Last
let i = Ipv4AddrRange::new(
Ipv4Addr::from_str("10.0.0.0").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!(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!(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()
);
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();
assert_eq!(i2.nth(1), Some(Ipv4Addr::from_str("10.0.0.1").unwrap()));
assert_eq!(i2.nth(1), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
assert_eq!(i2.nth(0), None);
let mut i3 = i.clone();
assert_eq!(i3.nth(99), None);
assert_eq!(i3.next(), None);
let i = Ipv6AddrRange::new(
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(4), None);
assert_eq!(i.clone().nth(99), None);
let mut i2 = i.clone();
assert_eq!(i2.nth(1), Some(Ipv6Addr::from_str("fd00::1").unwrap()));
assert_eq!(i2.nth(1), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
assert_eq!(i2.nth(0), None);
let mut i3 = i.clone();
assert_eq!(i3.nth(99), None);
assert_eq!(i3.next(), None);
// Nth Back
let i = Ipv4AddrRange::new(
Ipv4Addr::from_str("10.0.0.0").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(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(0), None);
let mut i3 = i.clone();
assert_eq!(i3.nth_back(99), None);
assert_eq!(i3.next(), None);
let i = Ipv6AddrRange::new(
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(4), None);
assert_eq!(i.clone().nth_back(99), None);
let mut i2 = i.clone();
assert_eq!(i2.nth_back(1), Some(Ipv6Addr::from_str("fd00::2").unwrap()));
assert_eq!(i2.nth_back(1), Some(Ipv6Addr::from_str("fd00::").unwrap()));
assert_eq!(i2.nth_back(0), None);
let mut i3 = i.clone();
assert_eq!(i3.nth_back(99), None);
assert_eq!(i3.next(), None);
}
}

1762
zeroidc/vendor/ipnet/src/ipnet.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
use crate::Ipv4Net;
use crate::Ipv6Net;
use crate::IpNet;
use schemars::{JsonSchema, gen::SchemaGenerator, schema::{SubschemaValidation, Schema, SchemaObject, StringValidation, Metadata, SingleOrVec, InstanceType}};
impl JsonSchema for Ipv4Net {
fn schema_name() -> String {
"Ipv4Net".to_string()
}
fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
Schema::Object(SchemaObject {
metadata: Some(Box::new(Metadata {
title: Some("IPv4 network".to_string()),
description: Some("An IPv4 address with prefix length".to_string()),
examples: vec![
schemars::_serde_json::Value::String("0.0.0.0/0".to_string()),
schemars::_serde_json::Value::String("192.168.0.0/24".to_string()),
],
..Default::default()
})),
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
string: Some(Box::new(StringValidation {
max_length: Some(18),
min_length: None,
pattern: Some(r#"^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(?:3[0-2]|[1-2][0-9]|[0-9])$"#.to_string()),
..Default::default()
})),
..Default::default()
})
}
}
impl JsonSchema for Ipv6Net {
fn schema_name() -> String {
"Ipv6Net".to_string()
}
fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
Schema::Object(SchemaObject {
metadata: Some(Box::new(Metadata {
title: Some("IPv6 network".to_string()),
description: Some("An IPv6 address with prefix length".to_string()),
examples: vec![
schemars::_serde_json::Value::String("::/0".to_string()),
schemars::_serde_json::Value::String("fd00::/32".to_string()),
],
..Default::default()
})),
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
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()),
..Default::default()
})),
..Default::default()
})
}
}
impl JsonSchema for IpNet {
fn schema_name() -> String {
"IpNet".to_string()
}
fn json_schema(gen: &mut SchemaGenerator) -> Schema {
Schema::Object(SchemaObject {
metadata: Some(Box::new(Metadata {
title: Some("IP network".to_string()),
description: Some("An IPv4 or IPv6 address with prefix length".to_string()),
examples: vec![
schemars::_serde_json::Value::String("192.168.0.0/24".to_string()),
schemars::_serde_json::Value::String("fd00::/32".to_string()),
],
..Default::default()
})),
subschemas: Some(Box::new(
SubschemaValidation {
one_of: Some(vec![Ipv4Net::json_schema(gen), Ipv6Net::json_schema(gen)]),
..Default::default()
}
)),
..Default::default()
})
}
}

276
zeroidc/vendor/ipnet/src/ipnet_serde.rs vendored Normal file
View File

@@ -0,0 +1,276 @@
use crate::{IpNet, Ipv4Net, Ipv6Net};
use std::fmt;
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
if serializer.is_human_readable() {
match *self {
IpNet::V4(ref a) => a.serialize(serializer),
IpNet::V6(ref a) => a.serialize(serializer),
}
} else {
match *self {
IpNet::V4(ref a) => serializer.serialize_newtype_variant("IpNet", 0, "V4", a),
IpNet::V6(ref a) => serializer.serialize_newtype_variant("IpNet", 1, "V6", a),
}
}
}
}
impl<'de> Deserialize<'de> for IpNet {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
if deserializer.is_human_readable() {
struct IpNetVisitor;
impl<'de> Visitor<'de> for IpNetVisitor {
type Value = IpNet;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("IPv4 or IPv6 network address")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where E: Error
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(IpNetVisitor)
} else {
struct EnumVisitor;
#[derive(Serialize, Deserialize)]
enum IpNetKind {
V4,
V6,
}
impl<'de> Visitor<'de> for EnumVisitor {
type Value = IpNet;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("IPv4 or IPv6 network address")
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where A: EnumAccess<'de>
{
match data.variant()? {
(IpNetKind::V4, v) => v.newtype_variant().map(IpNet::V4),
(IpNetKind::V6, v) => v.newtype_variant().map(IpNet::V6),
}
}
}
deserializer.deserialize_enum("IpNet", &["V4", "V6"], EnumVisitor)
}
}
}
impl Serialize for Ipv4Net {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
if serializer.is_human_readable() {
serializer.serialize_str(&self.to_string())
} else {
let mut seq = serializer.serialize_tuple(5)?;
for octet in &self.addr().octets() {
seq.serialize_element(octet)?;
}
seq.serialize_element(&self.prefix_len())?;
seq.end()
}
}
}
impl<'de> Deserialize<'de> for Ipv4Net {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
if deserializer.is_human_readable() {
struct IpAddrVisitor;
impl<'de> Visitor<'de> for IpAddrVisitor {
type Value = Ipv4Net;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("IPv4 network address")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where E: Error
{
s.parse().map_err(Error::custom)
}
}
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)
}
}
}
impl Serialize for Ipv6Net {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
if serializer.is_human_readable() {
serializer.serialize_str(&self.to_string())
} else {
let mut seq = serializer.serialize_tuple(17)?;
for octet in &self.addr().octets() {
seq.serialize_element(octet)?;
}
seq.serialize_element(&self.prefix_len())?;
seq.end()
}
}
}
impl<'de> Deserialize<'de> for Ipv6Net {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
if deserializer.is_human_readable() {
struct IpAddrVisitor;
impl<'de> Visitor<'de> for IpAddrVisitor {
type Value = Ipv6Net;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("IPv6 network address")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where E: Error
{
s.parse().map_err(Error::custom)
}
}
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)
}
}
}
#[cfg(test)]
mod tests {
extern crate serde_test;
use crate::{IpNet, Ipv4Net, Ipv6Net};
use self::serde_test::{assert_tokens, Configure, Token};
#[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,
]);
}
#[test]
fn test_serialize_ipnet_v6() {
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,
]);
}
#[test]
fn test_serialize_ipv4_net() {
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,
]);
}
#[test]
fn test_serialize_ipv6_net() {
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,
]);
}
}

96
zeroidc/vendor/ipnet/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,96 @@
#![doc(html_root_url = "https://docs.rs/ipnet/2.5.0")]
//! Types for IPv4 and IPv6 network addresses.
//!
//! This module provides types and useful methods for working with IPv4
//! and IPv6 network addresses, commonly called IP prefixes. The new
//! [`IpNet`], [`Ipv4Net`], and [`Ipv6Net`] types build on the existing
//! [`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
//! [`Ipv6AddrRange`] types for iterating over IP addresses in a range.
//! And traits that extend `Ipv4Addr` and `Ipv6Addr` with methods for
//! addition, subtraction, bitwise-and, and bitwise-or operations that
//! are missing in Rust's standard library.
//!
//! The module only uses stable features so it is guaranteed to compile
//! using the stable toolchain.
//!
//! # Organization
//!
//! * [`IpNet`] represents an IP network address, either IPv4 or IPv6.
//! * [`Ipv4Net`] and [`Ipv6Net`] are respectively IPv4 and IPv6 network
//! addresses.
//! * [`IpSubnets`], [`Ipv4Subnets`], and [`Ipv6Subnets`] are iterators
//! that generate the smallest set of IP network addresses bound by an
//! IP address range and minimum prefix length. These can be created
//! using their constructors. They are also returned by the
//! [`subnets()`] methods and used within the [`aggregate()`] methods.
//! * [`IpAddrRange`], [`Ipv4AddrRange`], and [`Ipv6AddrRange`] are
//! iterators that generate IP addresses. These can be created using
//! their constructors. They are also returned by the [`hosts()`]
//! methods.
//! * The [`IpAdd`], [`IpSub`], [`IpBitAnd`], [`IpBitOr`] traits extend
//! the [`Ipv4Addr`] and [`Ipv6Addr`] types with methods to perform
//! these operations.
//!
//! [`IpNet`]: enum.IpNet.html
//! [`Ipv4Net`]: struct.Ipv4Net.html
//! [`Ipv6Net`]: struct.Ipv6Net.html
//! [`IpAddr`]: https://doc.rust-lang.org/std/net/enum.IpAddr.html
//! [`Ipv4Addr`]: https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html
//! [`Ipv6Addr`]: https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html
//! [`IpSubnets`]: enum.IpSubnets.html
//! [`Ipv4Subnets`]: struct.Ipv4Subnets.html
//! [`Ipv6Subnets`]: struct.Ipv6Subnets.html
//! [`subnets()`]: enum.IpNet.html#method.subnets
//! [`aggregate()`]: enum.IpNet.html#method.aggregate
//! [`IpAddrRange`]: enum.IpAddrRange.html
//! [`Ipv4AddrRange`]: struct.Ipv4AddrRange.html
//! [`Ipv6AddrRange`]: struct.Ipv6AddrRange.html
//! [`hosts()`]: enum.IpNet.html#method.hosts
//! [`IpAdd`]: trait.IpAdd.html
//! [`IpSub`]: trait.IpSub.html
//! [`IpBitAnd`]: trait.IpBitAnd.html
//! [`IpBitOr`]: trait.IpBitOr.html
//!
//! # Serde support
//!
//! 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"] }
//! ```
//!
//! 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
//! length. The `IpNet` type will serialize to an Enum with the V4 or V6
//! variant index prepending the above string of 5 or 17 bytes.
//!
//! [feature]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(feature = "schemars")]
extern crate schemars;
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;
mod ipext;
mod ipnet;
mod parser;
#[cfg(feature = "serde")]
mod ipnet_serde;
#[cfg(feature = "schemars")]
mod ipnet_schemars;

345
zeroidc/vendor/ipnet/src/parser.rs vendored Normal file
View File

@@ -0,0 +1,345 @@
//! A private parser implementation of IPv4 and IPv6 network addresses.
//!
//! The existing `std::net::parser` module cannot be extended because it
//! is private. It is copied and extended here with methods for parsing
//! IP network addresses.
use std::error::Error;
use std::fmt;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
use crate::ipnet::{IpNet, Ipv4Net, Ipv6Net};
pub struct Parser<'a> {
// parsing as ASCII, so can use byte array
s: &'a [u8],
pos: usize,
}
impl<'a> Parser<'a> {
fn new(s: &'a str) -> Parser<'a> {
Parser {
s: s.as_bytes(),
pos: 0,
}
}
fn is_eof(&self) -> bool {
self.pos == self.s.len()
}
// Commit only if parser returns Some
fn read_atomically<T, F>(&mut self, cb: F) -> Option<T> where
F: FnOnce(&mut Parser) -> Option<T>,
{
let pos = self.pos;
let r = cb(self);
if r.is_none() {
self.pos = pos;
}
r
}
// Commit only if parser read till EOF
fn read_till_eof<T, F>(&mut self, cb: F) -> Option<T> where
F: FnOnce(&mut Parser) -> Option<T>,
{
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<T>(&mut self, parsers: &mut [Box<dyn FnMut(&mut Parser) -> Option<T> + 'static>])
-> Option<T> {
for pf in parsers {
if let Some(r) = self.read_atomically(|p: &mut Parser| pf(p)) {
return Some(r);
}
}
None
}
// Apply 3 parsers sequentially
fn read_seq_3<A, B, C, PA, PB, PC>(&mut self,
pa: PA,
pb: PB,
pc: PC)
-> Option<(A, B, C)> where
PA: FnOnce(&mut Parser) -> Option<A>,
PB: FnOnce(&mut Parser) -> Option<B>,
PC: FnOnce(&mut Parser) -> Option<C>,
{
self.read_atomically(move |p| {
let a = pa(p);
let b = if a.is_some() { pb(p) } else { None };
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
}
})
}
// Read next char
fn read_char(&mut self) -> Option<char> {
if self.is_eof() {
None
} else {
let r = self.s[self.pos] as char;
self.pos += 1;
Some(r)
}
}
// Return char and advance iff next char is equal to requested
fn read_given_char(&mut self, c: char) -> Option<char> {
self.read_atomically(|p| {
match p.read_char() {
Some(next) if next == c => Some(next),
_ => None,
}
})
}
// Read digit
fn read_digit(&mut self, radix: u8) -> Option<u8> {
fn parse_digit(c: char, radix: u8) -> Option<u8> {
let c = c as u8;
// assuming radix is either 10 or 16
if c >= b'0' && c <= b'9' {
Some(c - b'0')
} else if radix > 10 && c >= b'a' && c < b'a' + (radix - 10) {
Some(c - b'a' + 10)
} else if radix > 10 && c >= b'A' && c < b'A' + (radix - 10) {
Some(c - b'A' + 10)
} else {
None
}
}
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<u32> {
let mut r = 0;
let mut digit_count = 0;
loop {
match self.read_digit(radix) {
Some(d) => {
r = r * (radix as u32) + (d as u32);
digit_count += 1;
if digit_count > max_digits || r >= upto {
return None
}
}
None => {
if digit_count == 0 {
return None
} else {
return Some(r)
}
}
};
}
}
// Read number, failing if max_digits of number value exceeded
fn read_number(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
self.read_atomically(|p| p.read_number_impl(radix, max_digits, upto))
}
fn read_ipv4_addr_impl(&mut self) -> Option<Ipv4Addr> {
let mut bs = [0; 4];
let mut i = 0;
while i < 4 {
if i != 0 && self.read_given_char('.').is_none() {
return None;
}
let octet = self.read_number(10, 3, 0x100).map(|n| n as u8);
match octet {
Some(d) => bs[i] = d,
None => return None,
};
i += 1;
}
Some(Ipv4Addr::new(bs[0], bs[1], bs[2], bs[3]))
}
// Read IPv4 address
fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> {
self.read_atomically(|p| p.read_ipv4_addr_impl())
}
fn read_ipv6_addr_impl(&mut self) -> Option<Ipv6Addr> {
fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> Ipv6Addr {
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);
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) {
let mut i = 0;
while i < limit {
if i < limit - 1 {
let ipv4 = p.read_atomically(|p| {
if i == 0 || p.read_given_char(':').is_some() {
p.read_ipv4_addr()
} else {
None
}
});
if let Some(v4_addr) = ipv4 {
let octets = v4_addr.octets();
groups[i + 0] = ((octets[0] as u16) << 8) | (octets[1] as u16);
groups[i + 1] = ((octets[2] as u16) << 8) | (octets[3] as u16);
return (i + 2, true);
}
}
let group = p.read_atomically(|p| {
if i == 0 || p.read_given_char(':').is_some() {
p.read_number(16, 4, 0x10000).map(|n| n as u16)
} else {
None
}
});
match group {
Some(g) => groups[i] = g,
None => return (i, false)
}
i += 1;
}
(i, false)
}
let mut head = [0; 8];
let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
if head_size == 8 {
return Some(Ipv6Addr::new(
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
}
// read `::` if previous code parsed less than 8 groups
if !self.read_given_char(':').is_some() || !self.read_given_char(':').is_some() {
return None;
}
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]))
}
fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> {
self.read_atomically(|p| p.read_ipv6_addr_impl())
}
/* Additions for IpNet below. */
// Read IPv4 network
fn read_ipv4_net(&mut self) -> Option<Ipv4Net> {
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)
};
self.read_seq_3(ip_addr, slash, prefix_len).map(|t| {
let (ip, _, prefix_len): (Ipv4Addr, char, u8) = t;
Ipv4Net::new(ip, prefix_len).unwrap()
})
}
// Read Ipv6 network
fn read_ipv6_net(&mut self) -> Option<Ipv6Net> {
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)
};
self.read_seq_3(ip_addr, slash, prefix_len).map(|t| {
let (ip, _, prefix_len): (Ipv6Addr, char, u8) = t;
Ipv6Net::new(ip, prefix_len).unwrap()
})
}
fn read_ip_net(&mut self) -> Option<IpNet> {
let ipv4_net = |p: &mut Parser| p.read_ipv4_net().map(IpNet::V4);
let ipv6_net = |p: &mut Parser| p.read_ipv6_net().map(IpNet::V6);
self.read_or(&mut [Box::new(ipv4_net), Box::new(ipv6_net)])
}
/* Additions for IpNet above. */
}
/* Additions for IpNet below. */
impl FromStr for IpNet {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<IpNet, AddrParseError> {
match Parser::new(s).read_till_eof(|p| p.read_ip_net()) {
Some(s) => Ok(s),
None => Err(AddrParseError(()))
}
}
}
impl FromStr for Ipv4Net {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<Ipv4Net, AddrParseError> {
match Parser::new(s).read_till_eof(|p| p.read_ipv4_net()) {
Some(s) => Ok(s),
None => Err(AddrParseError(()))
}
}
}
impl FromStr for Ipv6Net {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<Ipv6Net, AddrParseError> {
match Parser::new(s).read_till_eof(|p| p.read_ipv6_net()) {
Some(s) => Ok(s),
None => Err(AddrParseError(()))
}
}
}
/* Additions for IpNet above. */
/// An error which can be returned when parsing an IP network address.
///
/// This error is used as the error type for the [`FromStr`] implementation for
/// [`IpNet`], [`Ipv4Net`], and [`Ipv6Net`].
///
/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
/// [`IpNet`]: enum.IpNet.html
/// [`Ipv4Net`]: struct.Ipv4Net.html
/// [`Ipv6Net`]: struct.Ipv6Net.html
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AddrParseError(());
impl fmt::Display for AddrParseError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("invalid IP address syntax")
}
}
impl Error for AddrParseError {}