use std::net::{Ipv4Addr, Ipv6Addr}; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct IPAddrBlocks { pub ips: Vec, } // IP Address Family #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct IPAddressFamily { pub address_family: Afi, pub ip_address_choice: IPAddressChoice, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)] pub enum Afi { Ipv4, Ipv6, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum IPAddressChoice { Inherit, AddressOrRange(Vec), } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum IPAddressOrRange { AddressPrefix(IPAddressPrefix), AddressRange(IPAddressRange), } #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)] pub struct IPAddressPrefix { pub address: IPAddress, pub prefix_length: u8, } impl IPAddressPrefix { pub fn new(address: IPAddress, prefix_length: u8) -> Self { Self { address, prefix_length, } } pub fn is_ipv4(&self) -> bool { self.address.is_ipv4() } pub fn is_ipv6(&self) -> bool { self.address.is_ipv6() } pub fn afi(&self) -> Afi { self.address.afi() } pub fn address(&self) -> IPAddress { self.address } pub fn prefix_length(&self) -> u8 { self.prefix_length } } #[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)] pub struct IPAddressRange { pub min: IPAddress, pub max: IPAddress, } impl IPAddressRange { pub fn new(min: IPAddress, max: IPAddress) -> Self { Self { min, max } } pub fn min(&self) -> IPAddress { self.min } pub fn max(&self) -> IPAddress { self.max } } #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum IPAddress { V4(Ipv4Addr), V6(Ipv6Addr), } impl IPAddress { pub fn from_ipv4(addr: Ipv4Addr) -> Self { Self::V4(addr) } pub fn from_ipv6(addr: Ipv6Addr) -> Self { Self::V6(addr) } pub fn to_ipv4(self) -> Option { match self { Self::V4(addr) => Some(addr), Self::V6(_) => None, } } pub fn to_ipv6(self) -> Option { match self { Self::V4(_) => None, Self::V6(addr) => Some(addr), } } pub fn is_ipv4(self) -> bool { matches!(self, Self::V4(_)) } pub fn is_ipv6(self) -> bool { matches!(self, Self::V6(_)) } pub fn afi(self) -> Afi { match self { Self::V4(_) => Afi::Ipv4, Self::V6(_) => Afi::Ipv6, } } /// Returns the numeric address value. /// /// For IPv4, this is the 32-bit address widened to u128. /// For IPv6, this is the full 128-bit address. pub fn as_u128(self) -> u128 { match self { Self::V4(addr) => u32::from(addr) as u128, Self::V6(addr) => u128::from(addr), } } pub fn as_v4_u32(self) -> Option { match self { Self::V4(addr) => Some(u32::from(addr)), Self::V6(_) => None, } } pub fn as_v6_u128(self) -> Option { match self { Self::V4(_) => None, Self::V6(addr) => Some(u128::from(addr)), } } }