21 Commits

Author SHA1 Message Date
cdd3dff549 Merge pull request #44 from achanda/release
Uprev for release
2017-04-13 16:41:36 +01:00
ef378f9921 Uprev for release 2017-04-13 16:40:13 +01:00
b70b551561 Merge pull request #43 from faern/fix-doc-test
Fix failing doc test
2017-04-03 09:22:18 +01:00
b442a7d598 Merge pull request #42 from faern/simplify-from-str
Simplify IpNetwork::from_str impl and update docs
2017-04-03 09:22:06 +01:00
5020a99401 Add punctuation 2017-04-02 18:56:25 +02:00
24c9a24dae Fix failing doc test 2017-04-02 17:51:30 +02:00
b3fd9f4f48 Simplify IpNetwork::from_str impl and update docs 2017-04-02 17:50:20 +02:00
04d454b5ba Merge pull request #41 from faern/impl-display
Implement Display for IpNetwork
2017-04-02 16:47:48 +01:00
f61db46006 Implement Display for IpNetwork 2017-04-02 17:30:06 +02:00
6980958412 Merge pull request #40 from achanda/release
Uprev for release
2017-02-23 09:42:13 +00:00
6647093bd8 Uprev for release 2017-02-23 09:38:14 +00:00
b7e23856d9 Merge pull request #38 from KeenS/impl_error
implement Error for IpNetworkError
2017-02-23 08:29:45 +00:00
c50ccbbd1a implement Error for IpNetworkError 2017-02-23 17:28:00 +09:00
4a5f0ee9e3 Merge pull request #39 from achanda/breakage
Remove the offending doc test for now
2017-02-23 08:26:29 +00:00
e128b5965b Remove the offending doc test for now 2017-02-23 08:22:36 +00:00
5cc374b164 Merge pull request #36 from cholcombe973/master
Add from_str helper to IpNetwork
2017-01-19 16:30:52 +00:00
0b71d8637f Add from_str helper to IpNetwork 2017-01-19 08:10:26 -08:00
9775590d40 Merge pull request #35 from achanda/empty_space
Remove some empty spaces
2017-01-10 17:43:26 +00:00
4c6e2ef69d Remove some empty spaces 2017-01-10 17:41:19 +00:00
dc1be6df69 Merge pull request #34 from achanda/is_version
Add two methods to check IP version
2016-12-28 23:36:27 +00:00
8f6710448a Add two methods to check IP version 2016-12-28 23:32:52 +00:00
3 changed files with 110 additions and 13 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "ipnetwork"
version = "0.12.1"
version = "0.12.3"
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"

View File

@ -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 {

View File

@ -5,12 +5,15 @@
#![cfg_attr(feature = "dev", plugin(clippy))]
#![crate_type = "lib"]
use std::fmt;
use std::net::IpAddr;
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 +39,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()),
@ -68,14 +62,18 @@ impl IpNetwork {
}
}
/// Returns the mask of the given `IpNetwork`
/// Returns the mask for this `IpNetwork`.
/// That means the `prefix` most significant bits will be 1 and the rest 0
///
/// # Example
/// ```
/// use ipnetwork::IpNetwork;
/// use std::net::{Ipv4Addr, Ipv6Addr};
///
/// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).mask(), 16u8);
/// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).mask(), 32u8);
/// let v4_net: IpNetwork = "10.9.0.32/16".parse().unwrap();
/// assert_eq!(v4_net.mask(), Ipv4Addr::new(255, 255, 0, 0));
/// let v6_net: IpNetwork = "ff01::0/32".parse().unwrap();
/// assert_eq!(v6_net.mask(), Ipv6Addr::new(0xffff, 0xffff, 0, 0, 0, 0, 0, 0));
///```
pub fn mask(&self) -> IpAddr {
match *self {
@ -83,6 +81,71 @@ 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,
}
}
}
/// Tries to parse the given string into a `IpNetwork`. Will first try to parse
/// it as an `Ipv4Network` and if that fails as an `Ipv6Network`. If both
/// fails it will return an `InvalidAddr` error.
///
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnetwork::{IpNetwork, Ipv4Network};
///
/// 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, from_cidr);
/// ```
impl FromStr for IpNetwork {
type Err = IpNetworkError;
fn from_str(s: &str) -> Result<IpNetwork, IpNetworkError> {
if let Ok(net) = Ipv4Network::from_str(s) {
Ok(IpNetwork::V4(net))
} else if let Ok(net) = Ipv6Network::from_str(s) {
Ok(IpNetwork::V6(net))
} else {
Err(IpNetworkError::InvalidAddr(s.to_string()))
}
}
}
impl From<Ipv4Network> for IpNetwork {
@ -97,6 +160,15 @@ impl From<Ipv6Network> for IpNetwork {
}
}
impl fmt::Display for IpNetwork {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
IpNetwork::V4(net) => net.fmt(f),
IpNetwork::V6(net) => net.fmt(f),
}
}
}
/// Converts a `IpAddr` network mask into a prefix.
/// If the mask is invalid this will return an `IpNetworkError::InvalidPrefix`.
pub fn ip_mask_to_prefix(mask: IpAddr) -> Result<u8, IpNetworkError> {