diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-30 12:03:20 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-01-30 12:03:20 -0800 |
| commit | ac1a03d7422ba52749e4e513a46c8d2129c2c817 (patch) | |
| tree | cefa26a551d7703c5f8534cc6661432348c93e06 /src/libstd | |
| parent | 0ba812fbf00e3026b29282e1a72d58ea7959833e (diff) | |
| parent | 0cdde6e5e015ee6f6d9381ab624a312af7c9b069 (diff) | |
| download | rust-ac1a03d7422ba52749e4e513a46c8d2129c2c817.tar.gz rust-ac1a03d7422ba52749e4e513a46c8d2129c2c817.zip | |
rollup merge of #21718: alexcrichton/stabilize-from-str
This commits adds an associated type to the `FromStr` trait representing an error payload for parses which do not succeed. The previous return value, `Option<Self>` did not allow for this form of payload. After the associated type was added, the following attributes were applied: * `FromStr` is now stable * `FromStr::Err` is now stable * `FromStr::from_str` is now stable * `StrExt::parse` is now stable * `FromStr for bool` is now stable * `FromStr for $float` is now stable * `FromStr for $integral` is now stable * Errors returned from stable `FromStr` implementations are stable * Errors implement `Display` and `Error` (both impl blocks being `#[stable]`) Closes #15138
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/num/uint_macros.rs | 20 | ||||
| -rw-r--r-- | src/libstd/old_io/net/ip.rs | 108 | ||||
| -rw-r--r-- | src/libstd/path/posix.rs | 13 | ||||
| -rw-r--r-- | src/libstd/path/windows.rs | 13 | ||||
| -rw-r--r-- | src/libstd/rt/util.rs | 4 |
5 files changed, 93 insertions, 65 deletions
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 82c55d7b5b8..4cd6391318f 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -20,7 +20,7 @@ mod tests { use num::FromStrRadix; fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> { - ::str::FromStr::from_str(t) + ::str::FromStr::from_str(t).ok() } #[test] @@ -38,15 +38,15 @@ mod tests { #[test] pub fn test_parse_bytes() { - assert_eq!(FromStrRadix::from_str_radix("123", 10), Some(123u as $T)); - assert_eq!(FromStrRadix::from_str_radix("1001", 2), Some(9u as $T)); - assert_eq!(FromStrRadix::from_str_radix("123", 8), Some(83u as $T)); - assert_eq!(FromStrRadix::from_str_radix("123", 16), Some(291u as u16)); - assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Some(65535u as u16)); - assert_eq!(FromStrRadix::from_str_radix("z", 36), Some(35u as $T)); - - assert_eq!(FromStrRadix::from_str_radix("Z", 10), None::<$T>); - assert_eq!(FromStrRadix::from_str_radix("_", 2), None::<$T>); + assert_eq!(FromStrRadix::from_str_radix("123", 10), Ok(123u as $T)); + assert_eq!(FromStrRadix::from_str_radix("1001", 2), Ok(9u as $T)); + assert_eq!(FromStrRadix::from_str_radix("123", 8), Ok(83u as $T)); + assert_eq!(FromStrRadix::from_str_radix("123", 16), Ok(291u as u16)); + assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Ok(65535u as u16)); + assert_eq!(FromStrRadix::from_str_radix("z", 36), Ok(35u as $T)); + + assert_eq!(FromStrRadix::from_str_radix("Z", 10).ok(), None::<$T>); + assert_eq!(FromStrRadix::from_str_radix("_", 2).ok(), None::<$T>); } #[test] diff --git a/src/libstd/old_io/net/ip.rs b/src/libstd/old_io/net/ip.rs index f0b73bd37f2..3e2e69f75a6 100644 --- a/src/libstd/old_io/net/ip.rs +++ b/src/libstd/old_io/net/ip.rs @@ -25,7 +25,7 @@ use iter::{Iterator, IteratorExt}; use ops::{FnOnce, FnMut}; use option::Option; use option::Option::{None, Some}; -use result::Result::{Ok, Err}; +use result::Result::{self, Ok, Err}; use slice::SliceExt; use str::{FromStr, StrExt}; use vec::Vec; @@ -350,17 +350,28 @@ impl<'a> Parser<'a> { } impl FromStr for IpAddr { - fn from_str(s: &str) -> Option<IpAddr> { - Parser::new(s).read_till_eof(|p| p.read_ip_addr()) + type Err = ParseError; + fn from_str(s: &str) -> Result<IpAddr, ParseError> { + match Parser::new(s).read_till_eof(|p| p.read_ip_addr()) { + Some(s) => Ok(s), + None => Err(ParseError), + } } } impl FromStr for SocketAddr { - fn from_str(s: &str) -> Option<SocketAddr> { - Parser::new(s).read_till_eof(|p| p.read_socket_addr()) + type Err = ParseError; + fn from_str(s: &str) -> Result<SocketAddr, ParseError> { + match Parser::new(s).read_till_eof(|p| p.read_socket_addr()) { + Some(s) => Ok(s), + None => Err(ParseError), + } } } +#[derive(Show, Clone, PartialEq, Copy)] +pub struct ParseError; + /// A trait for objects which can be converted or resolved to one or more `SocketAddr` values. /// /// Implementing types minimally have to implement either `to_socket_addr` or `to_socket_addr_all` @@ -493,7 +504,7 @@ fn parse_and_resolve_socket_addr(s: &str) -> IoResult<Vec<SocketAddr>> { let mut parts_iter = s.rsplitn(2, ':'); let port_str = try_opt!(parts_iter.next(), "invalid socket address"); let host = try_opt!(parts_iter.next(), "invalid socket address"); - let port: u16 = try_opt!(FromStr::from_str(port_str), "invalid port value"); + let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); resolve_socket_addr(host, port) } @@ -502,7 +513,7 @@ impl<'a> ToSocketAddr for (&'a str, u16) { let (host, port) = *self; // try to parse the host as a regular IpAddr first - match FromStr::from_str(host) { + match host.parse().ok() { Some(addr) => return Ok(vec![SocketAddr { ip: addr, port: port @@ -518,7 +529,7 @@ impl<'a> ToSocketAddr for (&'a str, u16) { impl<'a> ToSocketAddr for &'a str { fn to_socket_addr(&self) -> IoResult<SocketAddr> { // try to parse as a regular SocketAddr first - match FromStr::from_str(*self) { + match self.parse().ok() { Some(addr) => return Ok(addr), None => {} } @@ -535,7 +546,7 @@ impl<'a> ToSocketAddr for &'a str { fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> { // try to parse as a regular SocketAddr first - match FromStr::from_str(*self) { + match self.parse().ok() { Some(addr) => return Ok(vec![addr]), None => {} } @@ -553,95 +564,94 @@ mod test { #[test] fn test_from_str_ipv4() { - assert_eq!(Some(Ipv4Addr(127, 0, 0, 1)), FromStr::from_str("127.0.0.1")); - assert_eq!(Some(Ipv4Addr(255, 255, 255, 255)), FromStr::from_str("255.255.255.255")); - assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0")); + assert_eq!(Ok(Ipv4Addr(127, 0, 0, 1)), "127.0.0.1".parse()); + assert_eq!(Ok(Ipv4Addr(255, 255, 255, 255)), "255.255.255.255".parse()); + assert_eq!(Ok(Ipv4Addr(0, 0, 0, 0)), "0.0.0.0".parse()); // out of range - let none: Option<IpAddr> = FromStr::from_str("256.0.0.1"); + let none: Option<IpAddr> = "256.0.0.1".parse().ok(); assert_eq!(None, none); // too short - let none: Option<IpAddr> = FromStr::from_str("255.0.0"); + let none: Option<IpAddr> = "255.0.0".parse().ok(); assert_eq!(None, none); // too long - let none: Option<IpAddr> = FromStr::from_str("255.0.0.1.2"); + let none: Option<IpAddr> = "255.0.0.1.2".parse().ok(); assert_eq!(None, none); // no number between dots - let none: Option<IpAddr> = FromStr::from_str("255.0..1"); + let none: Option<IpAddr> = "255.0..1".parse().ok(); assert_eq!(None, none); } #[test] fn test_from_str_ipv6() { - assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("0:0:0:0:0:0:0:0")); - assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("0:0:0:0:0:0:0:1")); + assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), "0:0:0:0:0:0:0:0".parse()); + assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), "0:0:0:0:0:0:0:1".parse()); - assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("::1")); - assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("::")); + assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), "::1".parse()); + assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), "::".parse()); - assert_eq!(Some(Ipv6Addr(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)), - FromStr::from_str("2a02:6b8::11:11")); + assert_eq!(Ok(Ipv6Addr(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)), + "2a02:6b8::11:11".parse()); // too long group - let none: Option<IpAddr> = FromStr::from_str("::00000"); + let none: Option<IpAddr> = "::00000".parse().ok(); assert_eq!(None, none); // too short - let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7"); + let none: Option<IpAddr> = "1:2:3:4:5:6:7".parse().ok(); assert_eq!(None, none); // too long - let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7:8:9"); + let none: Option<IpAddr> = "1:2:3:4:5:6:7:8:9".parse().ok(); assert_eq!(None, none); // triple colon - let none: Option<IpAddr> = FromStr::from_str("1:2:::6:7:8"); + let none: Option<IpAddr> = "1:2:::6:7:8".parse().ok(); assert_eq!(None, none); // two double colons - let none: Option<IpAddr> = FromStr::from_str("1:2::6::8"); + let none: Option<IpAddr> = "1:2::6::8".parse().ok(); assert_eq!(None, none); } #[test] fn test_from_str_ipv4_in_ipv6() { - assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 49152, 545)), - FromStr::from_str("::192.0.2.33")); - assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)), - FromStr::from_str("::FFFF:192.0.2.33")); - assert_eq!(Some(Ipv6Addr(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)), - FromStr::from_str("64:ff9b::192.0.2.33")); - assert_eq!(Some(Ipv6Addr(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)), - FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33")); + assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 49152, 545)), + "::192.0.2.33".parse()); + assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)), + "::FFFF:192.0.2.33".parse()); + assert_eq!(Ok(Ipv6Addr(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)), + "64:ff9b::192.0.2.33".parse()); + assert_eq!(Ok(Ipv6Addr(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)), + "2001:db8:122:c000:2:2100:192.0.2.33".parse()); // colon after v4 - let none: Option<IpAddr> = FromStr::from_str("::127.0.0.1:"); + let none: Option<IpAddr> = "::127.0.0.1:".parse().ok(); assert_eq!(None, none); // not enough groups - let none: Option<IpAddr> = FromStr::from_str("1.2.3.4.5:127.0.0.1"); + let none: Option<IpAddr> = "1.2.3.4.5:127.0.0.1".parse().ok(); assert_eq!(None, none); // too many groups - let none: Option<IpAddr> = - FromStr::from_str("1.2.3.4.5:6:7:127.0.0.1"); + let none: Option<IpAddr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok(); assert_eq!(None, none); } #[test] fn test_from_str_socket_addr() { - assert_eq!(Some(SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 80 }), - FromStr::from_str("77.88.21.11:80")); - assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 }), - FromStr::from_str("[2a02:6b8:0:1::1]:53")); - assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0x7F00, 1), port: 22 }), - FromStr::from_str("[::127.0.0.1]:22")); + assert_eq!(Ok(SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 80 }), + "77.88.21.11:80".parse()); + assert_eq!(Ok(SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 }), + "[2a02:6b8:0:1::1]:53".parse()); + assert_eq!(Ok(SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0x7F00, 1), port: 22 }), + "[::127.0.0.1]:22".parse()); // without port - let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1"); + let none: Option<SocketAddr> = "127.0.0.1".parse().ok(); assert_eq!(None, none); // without port - let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:"); + let none: Option<SocketAddr> = "127.0.0.1:".parse().ok(); assert_eq!(None, none); // wrong brackets around v4 - let none: Option<SocketAddr> = FromStr::from_str("[127.0.0.1]:22"); + let none: Option<SocketAddr> = "[127.0.0.1]:22".parse().ok(); assert_eq!(None, none); // port out of range - let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:123456"); + let none: Option<SocketAddr> = "127.0.0.1:123456".parse().ok(); assert_eq!(None, none); } diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 588f724134e..72c41f2399e 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -19,6 +19,7 @@ use iter::{AdditiveIterator, Extend}; use iter::{Iterator, IteratorExt, Map}; use marker::Sized; use option::Option::{self, Some, None}; +use result::Result::{self, Ok, Err}; use slice::{AsSlice, Split, SliceExt, SliceConcatExt}; use str::{self, FromStr, StrExt}; use vec::Vec; @@ -86,11 +87,19 @@ impl Ord for Path { } impl FromStr for Path { - fn from_str(s: &str) -> Option<Path> { - Path::new_opt(s) + type Err = ParsePathError; + fn from_str(s: &str) -> Result<Path, ParsePathError> { + match Path::new_opt(s) { + Some(p) => Ok(p), + None => Err(ParsePathError), + } } } +/// Valuelue indicating that a path could not be parsed from a string. +#[derive(Show, Clone, PartialEq, Copy)] +pub struct ParsePathError; + impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path { #[inline] fn hash(&self, state: &mut S) { diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 98e0320cd14..e04f697b2a4 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -27,6 +27,7 @@ use mem; use option::Option::{self, Some, None}; #[cfg(stage0)] use ops::FullRange; +use result::Result::{self, Ok, Err}; use slice::{SliceExt, SliceConcatExt}; use str::{SplitTerminator, FromStr, StrExt}; use string::{String, ToString}; @@ -115,11 +116,19 @@ impl Ord for Path { } impl FromStr for Path { - fn from_str(s: &str) -> Option<Path> { - Path::new_opt(s) + type Err = ParsePathError; + fn from_str(s: &str) -> Result<Path, ParsePathError> { + match Path::new_opt(s) { + Some(p) => Ok(p), + None => Err(ParsePathError), + } } } +/// Value indicating that a path could not be parsed from a string. +#[derive(Show, Clone, PartialEq, Copy)] +pub struct ParsePathError; + impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path { #[cfg(not(test))] #[inline] diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index 4023a0a4c10..f5727a38b69 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -51,7 +51,7 @@ pub fn min_stack() -> uint { 0 => {} n => return n - 1, } - let amt = os::getenv("RUST_MIN_STACK").and_then(|s| s.parse()); + let amt = os::getenv("RUST_MIN_STACK").and_then(|s| s.parse().ok()); let amt = amt.unwrap_or(2 * 1024 * 1024); // 0 is our sentinel value, so ensure that we'll never see 0 after // initialization has run @@ -64,7 +64,7 @@ pub fn min_stack() -> uint { pub fn default_sched_threads() -> uint { match os::getenv("RUST_THREADS") { Some(nstr) => { - let opt_n: Option<uint> = nstr.parse(); + let opt_n: Option<uint> = nstr.parse().ok(); match opt_n { Some(n) if n > 0 => n, _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr) |
