about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-10-07 03:11:06 +0000
committerbors <bors@rust-lang.org>2020-10-07 03:11:06 +0000
commitc9ced8523bbb90561385aab305232f2167228a83 (patch)
tree5edeca2a3a5de2be241505d1912c61d4ec42341d /library/std/src
parent5779815f896fa6e21c04a5efb378aa6ba009a471 (diff)
parent49ade22bd990f5ad9165431a4c974e5d8b0e8732 (diff)
downloadrust-c9ced8523bbb90561385aab305232f2167228a83.tar.gz
rust-c9ced8523bbb90561385aab305232f2167228a83.zip
Auto merge of #77626 - tamird:parse-scope-id, r=dtolnay
Parse SocketAddrV6::scope_id

r? `@dtolnay`
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/net/parser.rs34
-rw-r--r--library/std/src/net/parser/tests.rs6
2 files changed, 27 insertions, 13 deletions
diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs
index 3a5fd8f6f5d..e8b89626fbd 100644
--- a/library/std/src/net/parser.rs
+++ b/library/std/src/net/parser.rs
@@ -32,7 +32,7 @@ macro_rules! impl_helper {
     })*)
 }
 
-impl_helper! { u8 u16 }
+impl_helper! { u8 u16 u32 }
 
 struct Parser<'a> {
     // parsing as ASCII, so can use byte array
@@ -75,9 +75,12 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Read the next character from the input if it matches the target
-    fn read_given_char(&mut self, target: char) -> Option<char> {
-        self.read_atomically(|p| p.read_char().filter(|&c| c == target))
+    #[must_use]
+    /// Read the next character from the input if it matches the target.
+    fn read_given_char(&mut self, target: char) -> Option<()> {
+        self.read_atomically(|p| {
+            p.read_char().and_then(|c| if c == target { Some(()) } else { None })
+        })
     }
 
     /// Helper for reading separators in an indexed loop. Reads the separator
@@ -90,7 +93,7 @@ impl<'a> Parser<'a> {
     {
         self.read_atomically(move |p| {
             if index > 0 {
-                let _ = p.read_given_char(sep)?;
+                p.read_given_char(sep)?;
             }
             inner(p)
         })
@@ -187,8 +190,8 @@ impl<'a> Parser<'a> {
 
             // read `::` if previous code parsed less than 8 groups
             // `::` indicates one or more groups of 16 bits of zeros
-            let _ = p.read_given_char(':')?;
-            let _ = p.read_given_char(':')?;
+            p.read_given_char(':')?;
+            p.read_given_char(':')?;
 
             // Read the back part of the address. The :: must contain at least one
             // set of zeroes, so our max length is 7.
@@ -211,7 +214,15 @@ impl<'a> Parser<'a> {
     /// Read a : followed by a port in base 10.
     fn read_port(&mut self) -> Option<u16> {
         self.read_atomically(|p| {
-            let _ = p.read_given_char(':')?;
+            p.read_given_char(':')?;
+            p.read_number(10, None)
+        })
+    }
+
+    /// Read a % followed by a scope id in base 10.
+    fn read_scope_id(&mut self) -> Option<u32> {
+        self.read_atomically(|p| {
+            p.read_given_char('%')?;
             p.read_number(10, None)
         })
     }
@@ -228,12 +239,13 @@ impl<'a> Parser<'a> {
     /// Read an IPV6 address with a port
     fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
         self.read_atomically(|p| {
-            let _ = p.read_given_char('[')?;
+            p.read_given_char('[')?;
             let ip = p.read_ipv6_addr()?;
-            let _ = p.read_given_char(']')?;
+            let scope_id = p.read_scope_id().unwrap_or(0);
+            p.read_given_char(']')?;
 
             let port = p.read_port()?;
-            Some(SocketAddrV6::new(ip, port, 0, 0))
+            Some(SocketAddrV6::new(ip, port, 0, scope_id))
         })
     }
 
diff --git a/library/std/src/net/parser/tests.rs b/library/std/src/net/parser/tests.rs
index ecf5a782c0c..8d8889cd19d 100644
--- a/library/std/src/net/parser/tests.rs
+++ b/library/std/src/net/parser/tests.rs
@@ -3,6 +3,7 @@ use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAdd
 use crate::str::FromStr;
 
 const PORT: u16 = 8080;
+const SCOPE_ID: u32 = 1337;
 
 const IPV4: Ipv4Addr = Ipv4Addr::new(192, 168, 0, 1);
 const IPV4_STR: &str = "192.168.0.1";
@@ -13,6 +14,7 @@ const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1";
 const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1";
 const IPV6_STR_V4: &str = "2001:db8::192.168.0.1";
 const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080";
+const IPV6_STR_PORT_SCOPE_ID: &str = "[2001:db8::c0a8:1%1337]:8080";
 
 #[test]
 fn parse_ipv4() {
@@ -74,8 +76,8 @@ fn parse_socket_v4() {
 
 #[test]
 fn parse_socket_v6() {
-    let result: SocketAddrV6 = IPV6_STR_PORT.parse().unwrap();
-    assert_eq!(result, SocketAddrV6::new(IPV6, PORT, 0, 0));
+    assert_eq!(IPV6_STR_PORT.parse(), Ok(SocketAddrV6::new(IPV6, PORT, 0, 0)));
+    assert_eq!(IPV6_STR_PORT_SCOPE_ID.parse(), Ok(SocketAddrV6::new(IPV6, PORT, 0, SCOPE_ID)));
 
     assert!(SocketAddrV6::from_str(IPV4_STR).is_err());
     assert!(SocketAddrV6::from_str(IPV4_STR_PORT).is_err());