From e15e8cb812c952280d5988833c2bacda33336f28 Mon Sep 17 00:00:00 2001 From: Abhishek Chanda Date: Sun, 9 Aug 2020 22:27:49 +0100 Subject: [PATCH] Implement TryFrom<&str> for all basic types Also improve some docs and FromStr type signature Closes #135 --- src/ipv4.rs | 12 ++++++++++-- src/ipv6.rs | 25 +++++++++++++++++++++++-- src/lib.rs | 12 ++++++++++-- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/ipv4.rs b/src/ipv4.rs index 51fb7e5..9b0395a 100644 --- a/src/ipv4.rs +++ b/src/ipv4.rs @@ -1,5 +1,5 @@ use crate::common::{cidr_parts, parse_prefix, IpNetworkError}; -use std::{fmt, net::Ipv4Addr, str::FromStr}; +use std::{fmt, net::Ipv4Addr, str::FromStr, convert::TryFrom}; const IPV4_BITS: u8 = 32; @@ -236,7 +236,7 @@ impl fmt::Display for Ipv4Network { /// ``` impl FromStr for Ipv4Network { type Err = IpNetworkError; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { let (addr_str, prefix_str) = cidr_parts(s)?; let addr = Ipv4Addr::from_str(addr_str) .map_err(|_| IpNetworkError::InvalidAddr(addr_str.to_string()))?; @@ -254,6 +254,14 @@ impl FromStr for Ipv4Network { } } +impl TryFrom<&str> for Ipv4Network { + type Error = IpNetworkError; + + fn try_from(s: &str) -> Result { + Ipv4Network::from_str(s) + } +} + impl From for Ipv4Network { fn from(a: Ipv4Addr) -> Ipv4Network { Ipv4Network { diff --git a/src/ipv6.rs b/src/ipv6.rs index 521c119..4013086 100644 --- a/src/ipv6.rs +++ b/src/ipv6.rs @@ -1,5 +1,5 @@ use crate::common::{cidr_parts, parse_prefix, IpNetworkError}; -use std::{cmp, fmt, net::Ipv6Addr, str::FromStr}; +use std::{cmp, fmt, net::Ipv6Addr, str::FromStr, convert::TryFrom}; const IPV6_BITS: u8 = 128; const IPV6_SEGMENT_BITS: u8 = 16; @@ -205,9 +205,22 @@ impl Ipv6Network { } } +/// Creates an `Ipv6Network` from parsing a string in CIDR notation. +/// +/// # Examples +/// +/// ``` +/// use std::net::Ipv6Addr; +/// use ipnetwork::Ipv6Network; +/// +/// let new = Ipv6Network::new(Ipv6Addr::new(0xff01, 0, 0, 0x17, 0, 0, 0, 0x2), 65).unwrap(); +/// let from_cidr: Ipv6Network = "FF01:0:0:17:0:0:0:2/65".parse().unwrap(); +/// assert_eq!(new.ip(), from_cidr.ip()); +/// assert_eq!(new.prefix(), from_cidr.prefix()); +/// ``` impl FromStr for Ipv6Network { type Err = IpNetworkError; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { let (addr_str, prefix_str) = cidr_parts(s)?; let addr = Ipv6Addr::from_str(addr_str) .map_err(|_| IpNetworkError::InvalidAddr(addr_str.to_string()))?; @@ -219,6 +232,14 @@ impl FromStr for Ipv6Network { } } +impl TryFrom<&str> for Ipv6Network { + type Error = IpNetworkError; + + fn try_from(s: &str) -> Result { + Ipv6Network::from_str(s) + } +} + impl From for Ipv6Network { fn from(a: Ipv6Addr) -> Ipv6Network { Ipv6Network { diff --git a/src/lib.rs b/src/lib.rs index b4b3948..5a02b4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,7 @@ unused_extern_crates, unused_import_braces)] -use std::{fmt, net::IpAddr, str::FromStr}; +use std::{fmt, net::IpAddr, str::FromStr, convert::TryFrom}; mod common; mod ipv4; @@ -282,7 +282,7 @@ impl IpNetwork { /// ``` impl FromStr for IpNetwork { type Err = IpNetworkError; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { if let Ok(net) = Ipv4Network::from_str(s) { Ok(IpNetwork::V4(net)) } else if let Ok(net) = Ipv6Network::from_str(s) { @@ -293,6 +293,14 @@ impl FromStr for IpNetwork { } } +impl TryFrom<&str> for IpNetwork { + type Error = IpNetworkError; + + fn try_from(s: &str) -> Result { + IpNetwork::from_str(s) + } +} + impl From for IpNetwork { fn from(v4: Ipv4Network) -> IpNetwork { IpNetwork::V4(v4)