Repository: achanda/ipnetwork (language: rust)

Issue:
Implement TryFrom<&str>
Right now there's just FromStr, which is not as robust. Should implement both.


Discussion / hints:

Fix patch:
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<Ipv4Network, IpNetworkError> {
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
         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<Self, Self::Error> {
+        Ipv4Network::from_str(s)
+    }
+}
+
 impl From<Ipv4Addr> 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<Ipv6Network, IpNetworkError> {
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
         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<Self, Self::Error> {
+        Ipv6Network::from_str(s)
+    }
+}
+
 impl From<Ipv6Addr> 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<IpNetwork, IpNetworkError> {
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
         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<Self, Self::Error> {
+        IpNetwork::from_str(s)
+    }
+}
+
 impl From<Ipv4Network> for IpNetwork {
     fn from(v4: Ipv4Network) -> IpNetwork {
         IpNetwork::V4(v4)


Test patch: