mirror of
https://github.com/achanda/ipnetwork.git
synced 2025-06-15 08:36:34 +00:00
64 lines
1.9 KiB
Rust
64 lines
1.9 KiB
Rust
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",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn cidr_parts(cidr: &str) -> Result<(&str, Option<&str>), IpNetworkError> {
|
|
// Try to find a single slash
|
|
if let Some(sep) = cidr.find('/') {
|
|
let (ip, prefix) = cidr.split_at(sep);
|
|
// Error if cidr has multiple slashes
|
|
if prefix[1..].find('/').is_some() {
|
|
Err(IpNetworkError::InvalidCidrFormat(format!(
|
|
"CIDR must contain a single '/': {cidr}"
|
|
)))
|
|
} else {
|
|
// Handle the case when cidr has exactly one slash
|
|
Ok((ip, Some(&prefix[1..])))
|
|
}
|
|
} else {
|
|
// Handle the case when cidr does not have a slash
|
|
Ok((cidr, None))
|
|
}
|
|
}
|
|
|
|
pub fn parse_prefix(prefix: &str, max: u8) -> Result<u8, IpNetworkError> {
|
|
prefix
|
|
.parse()
|
|
.map_err(|_| IpNetworkError::InvalidPrefix)
|
|
.and_then(|mask| {
|
|
if mask > max {
|
|
Err(IpNetworkError::InvalidPrefix)
|
|
} else {
|
|
Ok(mask)
|
|
}
|
|
})
|
|
}
|