mirror of
https://github.com/achanda/ipnetwork.git
synced 2025-06-16 00:48:10 +00:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
6980958412 | |||
6647093bd8 | |||
b7e23856d9 | |||
c50ccbbd1a | |||
4a5f0ee9e3 | |||
e128b5965b | |||
5cc374b164 | |||
0b71d8637f | |||
9775590d40 | |||
4c6e2ef69d | |||
dc1be6df69 | |||
8f6710448a |
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ipnetwork"
|
||||
version = "0.12.1"
|
||||
version = "0.12.2"
|
||||
authors = ["Abhishek Chanda <abhishek.becs@gmail.com>", "Linus Färnstrand <faern@faern.net>"]
|
||||
description = "A library to work with IP CIDRs in Rust, heavily WIP"
|
||||
license = "Apache-2.0"
|
||||
|
@ -1,4 +1,6 @@
|
||||
use std::net::Ipv4Addr;
|
||||
use std::fmt;
|
||||
use std::error::Error;
|
||||
|
||||
/// Represents a bunch of errors that can occur while working with a `IpNetwork`
|
||||
#[derive(Debug,Clone,PartialEq,Eq)]
|
||||
@ -8,6 +10,29 @@ pub enum IpNetworkError {
|
||||
InvalidCidrFormat(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for IpNetworkError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use IpNetworkError::*;
|
||||
match *self {
|
||||
InvalidAddr(ref s) => write!(f, "invalid address: {}", s),
|
||||
InvalidPrefix => write!(f, "invalid prifex"),
|
||||
InvalidCidrFormat(ref s) => write!(f, "invalid cidr format: {}", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for IpNetworkError {
|
||||
fn description(&self) -> &str {
|
||||
use IpNetworkError::*;
|
||||
match *self {
|
||||
InvalidAddr(_) => "address is invalid",
|
||||
InvalidPrefix => "prefix is invalid",
|
||||
InvalidCidrFormat(_) => "cidr is invalid",
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cidr_parts(cidr: &str) -> Result<(&str, &str), IpNetworkError> {
|
||||
let parts = cidr.split('/').collect::<Vec<&str>>();
|
||||
if parts.len() == 2 {
|
||||
|
79
src/lib.rs
79
src/lib.rs
@ -11,6 +11,8 @@ mod ipv4;
|
||||
mod ipv6;
|
||||
mod common;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
pub use ipv4::{Ipv4Network, ipv4_mask_to_prefix};
|
||||
pub use ipv6::{Ipv6Network, ipv6_mask_to_prefix};
|
||||
pub use common::IpNetworkError;
|
||||
@ -36,15 +38,6 @@ impl IpNetwork {
|
||||
}
|
||||
|
||||
/// Returns the IP part of a given `IpNetwork`
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
/// use ipnetwork::IpNetwork;
|
||||
///
|
||||
/// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).ip(), "10.9.0.32".parse().unwrap());
|
||||
/// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).ip(), "ff01::0".parse().unwrap());
|
||||
/// ```
|
||||
pub fn ip(&self) -> IpAddr {
|
||||
match *self {
|
||||
IpNetwork::V4(ref a) => IpAddr::V4(a.ip()),
|
||||
@ -83,6 +76,74 @@ impl IpNetwork {
|
||||
IpNetwork::V6(ref a) => IpAddr::V6(a.mask()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the IP in this `IpNetwork` is a valid IPv4 address,
|
||||
/// false if it's a valid IPv6 address.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
///```
|
||||
/// use ipnetwork::IpNetwork;
|
||||
///
|
||||
/// let v4: IpNetwork = IpNetwork::V4("10.9.0.32/16".parse().unwrap());
|
||||
/// assert_eq!(v4.is_ipv4(), true);
|
||||
/// assert_eq!(v4.is_ipv6(), false);
|
||||
///```
|
||||
pub fn is_ipv4(&self) -> bool {
|
||||
match *self {
|
||||
IpNetwork::V4(_) => true,
|
||||
IpNetwork::V6(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the IP in this `IpNetwork` is a valid IPv6 address,
|
||||
/// false if it's a valid IPv4 address.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
///```
|
||||
/// use ipnetwork::IpNetwork;
|
||||
///
|
||||
/// let v6: IpNetwork = IpNetwork::V6("ff01::0/32".parse().unwrap());
|
||||
/// assert_eq!(v6.is_ipv6(), true);
|
||||
/// assert_eq!(v6.is_ipv4(), false);
|
||||
///```
|
||||
pub fn is_ipv6(&self) -> bool {
|
||||
match *self {
|
||||
IpNetwork::V4(_) => false,
|
||||
IpNetwork::V6(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new `IpNetwork` from a given &str with a prefix denoting the
|
||||
/// network size. If the prefix is larger than 32 (for IPv4) or 128 (for IPv6), this
|
||||
/// will raise an `IpNetworkError::InvalidPrefix` error.
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::Ipv4Addr;
|
||||
/// use ipnetwork::Ipv4Network;
|
||||
/// use ipnetwork::IpNetwork;
|
||||
///
|
||||
/// let expected = IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(10, 1, 9, 32), 16).unwrap());
|
||||
/// let from_cidr: IpNetwork = "10.1.9.32/16".parse().unwrap();
|
||||
/// assert_eq!(expected.ip(), from_cidr.ip());
|
||||
/// assert_eq!(expected.prefix(), from_cidr.prefix());
|
||||
impl FromStr for IpNetwork {
|
||||
type Err = IpNetworkError;
|
||||
fn from_str(s: &str) -> Result<IpNetwork, IpNetworkError> {
|
||||
let v4addr: Result<Ipv4Network, IpNetworkError> = s.parse();
|
||||
let v6addr: Result<Ipv6Network, IpNetworkError> = s.parse();
|
||||
|
||||
if v4addr.is_ok() {
|
||||
Ok(IpNetwork::V4(v4addr.unwrap()))
|
||||
} else if v6addr.is_ok() {
|
||||
Ok(IpNetwork::V6(v6addr.unwrap()))
|
||||
} else {
|
||||
Err(IpNetworkError::InvalidAddr(s.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ipv4Network> for IpNetwork {
|
||||
|
Reference in New Issue
Block a user