Skip to content

Commit 8aa6a11

Browse files
committed
std: Implement FromStr for SocketAddrV{4,6}
This was already implemented for SocketAddr, so the other types are lacking it is just an oversight! Closes #29183
1 parent 5e9f305 commit 8aa6a11

File tree

2 files changed

+59
-17
lines changed

2 files changed

+59
-17
lines changed

src/libstd/net/ip.rs

+8
Original file line numberDiff line numberDiff line change
@@ -594,10 +594,18 @@ mod tests {
594594
fn test_from_str_socket_addr() {
595595
assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)),
596596
"77.88.21.11:80".parse());
597+
assert_eq!(Ok(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)),
598+
"77.88.21.11:80".parse());
597599
assert_eq!(Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)),
598600
"[2a02:6b8:0:1::1]:53".parse());
601+
assert_eq!(Ok(SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1,
602+
0, 0, 0, 1), 53, 0, 0)),
603+
"[2a02:6b8:0:1::1]:53".parse());
599604
assert_eq!(Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)),
600605
"[::127.0.0.1]:22".parse());
606+
assert_eq!(Ok(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0,
607+
0x7F00, 1), 22, 0, 0)),
608+
"[::127.0.0.1]:22".parse());
601609

602610
// without port
603611
let none: Option<SocketAddr> = "127.0.0.1".parse().ok();

src/libstd/net/parser.rs

+51-17
Original file line numberDiff line numberDiff line change
@@ -267,30 +267,42 @@ impl<'a> Parser<'a> {
267267
self.read_or(&mut [Box::new(ipv4_addr), Box::new(ipv6_addr)])
268268
}
269269

270-
fn read_socket_addr(&mut self) -> Option<SocketAddr> {
270+
fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> {
271+
let ip_addr = |p: &mut Parser| p.read_ipv4_addr();
272+
let colon = |p: &mut Parser| p.read_given_char(':');
273+
let port = |p: &mut Parser| {
274+
p.read_number(10, 5, 0x10000).map(|n| n as u16)
275+
};
276+
277+
self.read_seq_3(ip_addr, colon, port).map(|t| {
278+
let (ip, _, port): (Ipv4Addr, char, u16) = t;
279+
SocketAddrV4::new(ip, port)
280+
})
281+
}
282+
283+
fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
271284
let ip_addr = |p: &mut Parser| {
272-
let ipv4_p = |p: &mut Parser| p.read_ip_addr();
273-
let ipv6_p = |p: &mut Parser| {
274-
let open_br = |p: &mut Parser| p.read_given_char('[');
275-
let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
276-
let clos_br = |p: &mut Parser| p.read_given_char(']');
277-
p.read_seq_3::<char, Ipv6Addr, char, _, _, _>(open_br, ip_addr, clos_br)
278-
.map(|t| match t { (_, ip, _) => IpAddr::V6(ip) })
279-
};
280-
p.read_or(&mut [Box::new(ipv4_p), Box::new(ipv6_p)])
285+
let open_br = |p: &mut Parser| p.read_given_char('[');
286+
let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
287+
let clos_br = |p: &mut Parser| p.read_given_char(']');
288+
p.read_seq_3(open_br, ip_addr, clos_br).map(|t| t.1)
281289
};
282290
let colon = |p: &mut Parser| p.read_given_char(':');
283-
let port = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
291+
let port = |p: &mut Parser| {
292+
p.read_number(10, 5, 0x10000).map(|n| n as u16)
293+
};
284294

285-
// host, colon, port
286295
self.read_seq_3(ip_addr, colon, port).map(|t| {
287-
let (ip, _, port): (IpAddr, char, u16) = t;
288-
match ip {
289-
IpAddr::V4(ip) => SocketAddr::V4(SocketAddrV4::new(ip, port)),
290-
IpAddr::V6(ip) => SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0)),
291-
}
296+
let (ip, _, port): (Ipv6Addr, char, u16) = t;
297+
SocketAddrV6::new(ip, port, 0, 0)
292298
})
293299
}
300+
301+
fn read_socket_addr(&mut self) -> Option<SocketAddr> {
302+
let v4 = |p: &mut Parser| p.read_socket_addr_v4().map(SocketAddr::V4);
303+
let v6 = |p: &mut Parser| p.read_socket_addr_v6().map(SocketAddr::V6);
304+
self.read_or(&mut [Box::new(v4), Box::new(v6)])
305+
}
294306
}
295307

296308
#[stable(feature = "rust1", since = "1.0.0")]
@@ -326,6 +338,28 @@ impl FromStr for Ipv6Addr {
326338
}
327339
}
328340

341+
#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
342+
impl FromStr for SocketAddrV4 {
343+
type Err = AddrParseError;
344+
fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
345+
match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v4()) {
346+
Some(s) => Ok(s),
347+
None => Err(AddrParseError(())),
348+
}
349+
}
350+
}
351+
352+
#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
353+
impl FromStr for SocketAddrV6 {
354+
type Err = AddrParseError;
355+
fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
356+
match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v6()) {
357+
Some(s) => Ok(s),
358+
None => Err(AddrParseError(())),
359+
}
360+
}
361+
}
362+
329363
#[stable(feature = "rust1", since = "1.0.0")]
330364
impl FromStr for SocketAddr {
331365
type Err = AddrParseError;

0 commit comments

Comments
 (0)