Skip to content

Commit

Permalink
Add Ipv4Block and Ipv6Block. (#298)
Browse files Browse the repository at this point in the history
This PR adds new types Ipv4Block and Ipv6Block that wrap an IpBlock and
enforce it to be of the correct address family. In addition it adds
FromIterator impls to Ipv4Blocks and Ipv6Blocks.
  • Loading branch information
partim authored Jul 31, 2024
1 parent a7562a3 commit 32f7262
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 15 deletions.
152 changes: 141 additions & 11 deletions src/repository/resources/ipres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ impl IpBlock {
}
}

/// Returns whether the block is prefix with address length zero.
/// Returns whether the block is a prefix with address length zero.
pub fn is_slash_zero(&self) -> bool {
matches!(*self, IpBlock::Prefix(prefix) if prefix.len == 0)
}
Expand Down Expand Up @@ -1709,12 +1709,126 @@ impl AddressFamily {
}


//------------ Ipv4Blocks ----------------------------------------------------
//------------ Ipv4Block -----------------------------------------------------

/// A consecutive sequence of IPv4 addresses.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Ipv4Block(IpBlock);

impl Ipv4Block {
/// Creates a new block covering all IPv4 addresses.
pub fn all() -> Self {
Self(IpBlock::all())
}

/// Returns whether the block is prefix with address length zero.
pub fn is_slash_zero(&self) -> bool {
self.0.is_slash_zero()
}

/// The smallest address of the block.
pub fn min(&self) -> Ipv4Addr {
self.0.min().into()
}

/// The largest address of the block.
pub fn max(&self) -> Ipv4Addr {
self.0.max().into()
}
}


//--- From and FromStr

impl From<Ipv4Block> for IpBlock {
fn from(src: Ipv4Block) -> IpBlock {
src.0
}
}

impl str::FromStr for Ipv4Block {
type Err = FromStrError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(IpBlock::from_v4_str(s)?))
}
}


//--- Display

/// Contains IPv4 resources. This type is a thin wrapper around the underlying
/// [`IpBlocks`] type intended to help with serializing/deserializing and
/// formatting using IPv4 syntax.
impl fmt::Display for Ipv4Block {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt_v4(f)
}
}


//------------ Ipv6Block -----------------------------------------------------

/// A consecutive sequence of IPv6 addresses.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Ipv6Block(IpBlock);

impl Ipv6Block {
/// Creates a new block covering all IPv6 addresses.
pub fn all() -> Self {
Self(IpBlock::all())
}

/// Returns whether the block is prefix with address length zero.
pub fn is_slash_zero(&self) -> bool {
self.0.is_slash_zero()
}

/// The smallest address of the block.
pub fn min(&self) -> Ipv6Addr {
self.0.min().into()
}

/// The largest address of the block.
pub fn max(&self) -> Ipv6Addr {
self.0.max().into()
}
}


//--- From and FromStr

impl From<Ipv6Block> for IpBlock {
fn from(src: Ipv6Block) -> IpBlock {
src.0
}
}

impl str::FromStr for Ipv6Block {
type Err = FromStrError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(IpBlock::from_v6_str(s)?))
}
}


//--- Display

impl fmt::Display for Ipv6Block {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt_v6(f)
}
}


//------------ Ipv4Blocks ----------------------------------------------------

/// Multiple consecutive sequences of IPv4 addresses.
///
/// Values of this type are guaranteed to contain a sequence of
/// [`Ipv4Block`]s that fulfills the requirements of RFC 3779. Specifically,
/// the blocks will not overlap, will not be consecutive (i.e., there’s at
/// least one address between neighbouring blocks), will be in order, and
/// anything that can be addressed as a prefix will be.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Ipv4Blocks(IpBlocks);

impl Ipv4Blocks {
Expand All @@ -1740,7 +1854,7 @@ impl fmt::Display for Ipv4Blocks {
}
}

//--- FromStr
//--- FromStr and FromIterator

impl FromStr for Ipv4Blocks {
type Err = FromStrError;
Expand All @@ -1764,6 +1878,12 @@ impl FromStr for Ipv4Blocks {
}
}

impl FromIterator<Ipv4Block> for Ipv4Blocks {
fn from_iter<I: IntoIterator<Item = Ipv4Block>>(iter: I) -> Self {
Self(IpBlocks::from_iter(iter.into_iter().map(Into::into)))
}
}

//--- Serialize and Deserialize

#[cfg(feature = "serde")]
Expand Down Expand Up @@ -1802,10 +1922,14 @@ impl std::ops::Deref for Ipv4Blocks {

//------------ Ipv6Blocks ----------------------------------------------------

/// Contains IPv6 resources. This type is a thin wrapper around the underlying
/// [`IpBlocks`] type intended to help with serializing/deserializing and
/// formatting using IPv6 syntax.
#[derive(Clone, Debug, Eq, PartialEq)]
/// Multiple consecutive sequences of IPv6 addresses.
///
/// Values of this type are guaranteed to contain a sequence of
/// [`Ipv6Block`]s that fulfills the requirements of RFC 3779. Specifically,
/// the blocks will not overlap, will not be consecutive (i.e., there’s at
/// least one address between neighbouring blocks), will be in order, and
/// anything that can be addressed as a prefix will be.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Ipv6Blocks(IpBlocks);

impl Ipv6Blocks {
Expand All @@ -1831,7 +1955,7 @@ impl fmt::Display for Ipv6Blocks {
}
}

//--- FromStr
//--- FromStr and FromIterator

impl FromStr for Ipv6Blocks {
type Err = FromStrError;
Expand All @@ -1855,6 +1979,12 @@ impl FromStr for Ipv6Blocks {
}
}

impl FromIterator<Ipv6Block> for Ipv6Blocks {
fn from_iter<I: IntoIterator<Item = Ipv6Block>>(iter: I) -> Self {
Self(IpBlocks::from_iter(iter.into_iter().map(Into::into)))
}
}

//--- Serialize and Deserialize

#[cfg(feature = "serde")]
Expand Down
8 changes: 4 additions & 4 deletions src/repository/resources/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ pub use self::asres::{
};
pub use self::choice::ResourcesChoice;
pub use self::ipres::{
Addr, AddressFamily, InheritedIpResources, IpBlock, IpBlocks, Ipv4Blocks,
Ipv6Blocks, IpBlocksBuilder, IpBlocksForFamily, IpResources,
IpResourcesBuilder, OverclaimedIpResources, OverclaimedIpv4Resources,
OverclaimedIpv6Resources, Prefix
Addr, AddressFamily, InheritedIpResources, IpBlock, IpBlocks, Ipv4Block,
Ipv4Blocks, Ipv6Block, Ipv6Blocks, IpBlocksBuilder, IpBlocksForFamily,
IpResources, IpResourcesBuilder, OverclaimedIpResources,
OverclaimedIpv4Resources, OverclaimedIpv6Resources, Prefix
};
pub use self::set::{
ResourceDiff, ResourceSet
Expand Down

0 comments on commit 32f7262

Please sign in to comment.