diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 633e7326bb1..827a3eb9bf6 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -594,10 +594,18 @@ mod tests { fn test_from_str_socket_addr() { assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)), "77.88.21.11:80".parse()); + assert_eq!(Ok(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)), + "77.88.21.11:80".parse()); assert_eq!(Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)), "[2a02:6b8:0:1::1]:53".parse()); + assert_eq!(Ok(SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, + 0, 0, 0, 1), 53, 0, 0)), + "[2a02:6b8:0:1::1]:53".parse()); assert_eq!(Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)), "[::127.0.0.1]:22".parse()); + assert_eq!(Ok(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, + 0x7F00, 1), 22, 0, 0)), + "[::127.0.0.1]:22".parse()); // without port let none: Option = "127.0.0.1".parse().ok(); diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs index f0b35bbc388..1619dac78ca 100644 --- a/src/libstd/net/parser.rs +++ b/src/libstd/net/parser.rs @@ -267,30 +267,42 @@ impl<'a> Parser<'a> { self.read_or(&mut [Box::new(ipv4_addr), Box::new(ipv6_addr)]) } - fn read_socket_addr(&mut self) -> Option { + fn read_socket_addr_v4(&mut self) -> Option { + let ip_addr = |p: &mut Parser| p.read_ipv4_addr(); + let colon = |p: &mut Parser| p.read_given_char(':'); + let port = |p: &mut Parser| { + p.read_number(10, 5, 0x10000).map(|n| n as u16) + }; + + self.read_seq_3(ip_addr, colon, port).map(|t| { + let (ip, _, port): (Ipv4Addr, char, u16) = t; + SocketAddrV4::new(ip, port) + }) + } + + fn read_socket_addr_v6(&mut self) -> Option { let ip_addr = |p: &mut Parser| { - let ipv4_p = |p: &mut Parser| p.read_ip_addr(); - let ipv6_p = |p: &mut Parser| { - let open_br = |p: &mut Parser| p.read_given_char('['); - let ip_addr = |p: &mut Parser| p.read_ipv6_addr(); - let clos_br = |p: &mut Parser| p.read_given_char(']'); - p.read_seq_3::(open_br, ip_addr, clos_br) - .map(|t| match t { (_, ip, _) => IpAddr::V6(ip) }) - }; - p.read_or(&mut [Box::new(ipv4_p), Box::new(ipv6_p)]) + let open_br = |p: &mut Parser| p.read_given_char('['); + let ip_addr = |p: &mut Parser| p.read_ipv6_addr(); + let clos_br = |p: &mut Parser| p.read_given_char(']'); + p.read_seq_3(open_br, ip_addr, clos_br).map(|t| t.1) }; let colon = |p: &mut Parser| p.read_given_char(':'); - let port = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16); + let port = |p: &mut Parser| { + p.read_number(10, 5, 0x10000).map(|n| n as u16) + }; - // host, colon, port self.read_seq_3(ip_addr, colon, port).map(|t| { - let (ip, _, port): (IpAddr, char, u16) = t; - match ip { - IpAddr::V4(ip) => SocketAddr::V4(SocketAddrV4::new(ip, port)), - IpAddr::V6(ip) => SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0)), - } + let (ip, _, port): (Ipv6Addr, char, u16) = t; + SocketAddrV6::new(ip, port, 0, 0) }) } + + fn read_socket_addr(&mut self) -> Option { + let v4 = |p: &mut Parser| p.read_socket_addr_v4().map(SocketAddr::V4); + let v6 = |p: &mut Parser| p.read_socket_addr_v6().map(SocketAddr::V6); + self.read_or(&mut [Box::new(v4), Box::new(v6)]) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -326,6 +338,28 @@ impl FromStr for Ipv6Addr { } } +#[stable(feature = "socket_addr_from_str", since = "1.5.0")] +impl FromStr for SocketAddrV4 { + type Err = AddrParseError; + fn from_str(s: &str) -> Result { + match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v4()) { + Some(s) => Ok(s), + None => Err(AddrParseError(())), + } + } +} + +#[stable(feature = "socket_addr_from_str", since = "1.5.0")] +impl FromStr for SocketAddrV6 { + type Err = AddrParseError; + fn from_str(s: &str) -> Result { + match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v6()) { + Some(s) => Ok(s), + None => Err(AddrParseError(())), + } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl FromStr for SocketAddr { type Err = AddrParseError;