Skip to content

Commit

Permalink
impl Display for NetworkSize
Browse files Browse the repository at this point in the history
  • Loading branch information
ctrlcctrlv committed Jun 13, 2023
1 parent 3bc252d commit 5c91bd0
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 50 deletions.
50 changes: 50 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use std::{error::Error, fmt};

use crate::error::IpNetworkError::*;

/// Represents a bunch of errors that can occur while working with a `IpNetwork`
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum IpNetworkError {
InvalidAddr(String),
InvalidPrefix,
InvalidCidrFormat(String),
NetworkSizeError(NetworkSizeError)
}

impl fmt::Display for IpNetworkError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
InvalidAddr(ref s) => write!(f, "invalid address: {s}"),
InvalidPrefix => write!(f, "invalid prefix"),
InvalidCidrFormat(ref s) => write!(f, "invalid cidr format: {s}"),
NetworkSizeError(ref e) => write!(f, "network size error: {e}")
}
}
}

impl Error for IpNetworkError {
fn description(&self) -> &str {
match *self {
InvalidAddr(_) => "address is invalid",
InvalidPrefix => "prefix is invalid",
InvalidCidrFormat(_) => "cidr is invalid",
NetworkSizeError(_) => "network size error"
}
}
}

/// Cannot convert an IPv6 network size to a u32 as it is a 128-bit value.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum NetworkSizeError {
NetworkIsTooLarge
}

impl fmt::Display for NetworkSizeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("Network is too large to fit into an unsigned 32-bit integer!")
}
}

impl Error for NetworkSizeError {}
3 changes: 2 additions & 1 deletion src/ipv4.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::common::{cidr_parts, parse_prefix, IpNetworkError};
use crate::error::IpNetworkError;
use crate::parse::{cidr_parts, parse_prefix};
use std::{convert::TryFrom, fmt, net::Ipv4Addr, str::FromStr};

const IPV4_BITS: u8 = 32;
Expand Down
3 changes: 2 additions & 1 deletion src/ipv6.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::common::{cidr_parts, parse_prefix, IpNetworkError};
use crate::error::IpNetworkError;
use crate::parse::{cidr_parts, parse_prefix};
use std::{cmp, convert::TryFrom, fmt, net::Ipv6Addr, str::FromStr};

const IPV6_BITS: u8 = 128;
Expand Down
7 changes: 4 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@

use std::{convert::TryFrom, fmt, net::IpAddr, str::FromStr};

mod common;
mod error;
mod ipv4;
mod ipv6;
mod parse;
mod size;

pub use crate::common::IpNetworkError;
pub use crate::error::{NetworkSizeError, IpNetworkError};
pub use crate::ipv4::Ipv4NetworkIterator;
pub use crate::ipv4::{ipv4_mask_to_prefix, Ipv4Network};
pub use crate::ipv6::Ipv6NetworkIterator;
pub use crate::ipv6::{ipv6_mask_to_prefix, Ipv6Network};
pub use crate::size::{NetworkIsTooLargeError, NetworkSize};
pub use crate::size::NetworkSize;

/// Represents a generic network range. This type can have two variants:
/// the v4 and the v6 case.
Expand Down
32 changes: 1 addition & 31 deletions src/common.rs → src/parse.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,4 @@
use std::{error::Error, fmt};

/// Represents a bunch of errors that can occur while working with a `IpNetwork`
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum IpNetworkError {
InvalidAddr(String),
InvalidPrefix,
InvalidCidrFormat(String),
}

impl fmt::Display for IpNetworkError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::IpNetworkError::*;
match *self {
InvalidAddr(ref s) => write!(f, "invalid address: {s}"),
InvalidPrefix => write!(f, "invalid prefix"),
InvalidCidrFormat(ref s) => write!(f, "invalid cidr format: {s}"),
}
}
}

impl Error for IpNetworkError {
fn description(&self) -> &str {
use crate::IpNetworkError::*;
match *self {
InvalidAddr(_) => "address is invalid",
InvalidPrefix => "prefix is invalid",
InvalidCidrFormat(_) => "cidr is invalid",
}
}
}
use crate::error::IpNetworkError;

pub fn cidr_parts(cidr: &str) -> Result<(&str, Option<&str>), IpNetworkError> {
// Try to find a single slash
Expand Down
36 changes: 22 additions & 14 deletions src/size.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::{cmp::Ordering, error::Error, fmt::Display};
use std::{cmp::Ordering, fmt::Display};

use crate::error::NetworkSizeError;

/// Represents a generic network size. For IPv4, the max size is a u32 and for IPv6, it is a u128
#[derive(Debug, Clone, Copy, Hash)]
Expand All @@ -22,23 +24,12 @@ impl From<u32> for NetworkSize {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
/// Cannot convert an IPv6 network size to a u32 as it is a 128-bit value.
pub struct NetworkIsTooLargeError;

impl Display for NetworkIsTooLargeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("Network is too large to fit into an unsigned 32-bit integer!")
}
}
impl Error for NetworkIsTooLargeError {}

impl TryInto<u32> for NetworkSize {
type Error = NetworkIsTooLargeError;
type Error = NetworkSizeError;
fn try_into(self) -> Result<u32, Self::Error> {
match self {
V4(a) => Ok(a),
V6(_) => Err(NetworkIsTooLargeError),
V6(_) => Err(NetworkSizeError::NetworkIsTooLarge),
}
}
}
Expand Down Expand Up @@ -78,6 +69,16 @@ impl PartialOrd for NetworkSize {

impl Eq for NetworkSize {}

// Display

impl Display for NetworkSize {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", Into::<u128>::into(*self))
}
}

// Tests

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -150,4 +151,11 @@ mod tests {
let ns2 = V6(200);
assert!(ns1 < ns2);
}

#[test]
fn test_display() {
let ns1 = V4(u32::MAX);
let ns2 = V6(ns1.into());
assert_eq!(ns1.to_string(), ns2.to_string());
}
}

0 comments on commit 5c91bd0

Please sign in to comment.