Explorar el Código

Merge pull request #674 from 3scale-rs/add-authority-fn

url: add the authority method
Valentin Gosu hace 3 años
padre
commit
1c1e406874
Se han modificado 2 ficheros con 87 adiciones y 0 borrados
  1. 43 0
      url/src/lib.rs
  2. 44 0
      url/tests/unit.rs

+ 43 - 0
url/src/lib.rs

@@ -792,6 +792,8 @@ impl Url {
     /// URLs that do *not* are either path-only like `unix:/run/foo.socket`
     /// or cannot-be-a-base like `data:text/plain,Stuff`.
     ///
+    /// See also the `authority` method.
+    ///
     /// # Examples
     ///
     /// ```
@@ -817,6 +819,47 @@ impl Url {
         self.slice(self.scheme_end..).starts_with("://")
     }
 
+    /// Return the authority of this URL as an ASCII string.
+    ///
+    /// Non-ASCII domains are punycode-encoded per IDNA if this is the host
+    /// of a special URL, or percent encoded for non-special URLs.
+    /// IPv6 addresses are given between `[` and `]` brackets.
+    /// Ports are omitted if they match the well known port of a special URL.
+    ///
+    /// Username and password are percent-encoded.
+    ///
+    /// See also the `has_authority` method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use url::Url;
+    /// # use url::ParseError;
+    ///
+    /// # fn run() -> Result<(), ParseError> {
+    /// let url = Url::parse("unix:/run/foo.socket")?;
+    /// assert_eq!(url.authority(), "");
+    /// let url = Url::parse("file:///tmp/foo")?;
+    /// assert_eq!(url.authority(), "");
+    /// let url = Url::parse("https://user:password@example.com/tmp/foo")?;
+    /// assert_eq!(url.authority(), "user:password@example.com");
+    /// let url = Url::parse("irc://àlex.рф.example.com:6667/foo")?;
+    /// assert_eq!(url.authority(), "%C3%A0lex.%D1%80%D1%84.example.com:6667");
+    /// let url = Url::parse("http://àlex.рф.example.com:80/foo")?;
+    /// assert_eq!(url.authority(), "xn--lex-8ka.xn--p1ai.example.com");
+    /// # Ok(())
+    /// # }
+    /// # run().unwrap();
+    /// ```
+    pub fn authority(&self) -> &str {
+        let scheme_separator_len = "://".len() as u32;
+        if self.has_authority() && self.path_start > self.scheme_end + scheme_separator_len {
+            self.slice(self.scheme_end + scheme_separator_len..self.path_start)
+        } else {
+            ""
+        }
+    }
+
     /// Return whether this URL is a cannot-be-a-base URL,
     /// meaning that parsing a relative URL string with this URL as the base will return an error.
     ///

+ 44 - 0
url/tests/unit.rs

@@ -1162,3 +1162,47 @@ fn test_make_relative() {
         assert_eq!(make_relative, None, "base: {}, uri: {}", base, uri);
     }
 }
+
+#[test]
+fn test_has_authority() {
+    let url = Url::parse("mailto:joe@example.com").unwrap();
+    assert!(!url.has_authority());
+    let url = Url::parse("unix:/run/foo.socket").unwrap();
+    assert!(!url.has_authority());
+    let url = Url::parse("file:///tmp/foo").unwrap();
+    assert!(url.has_authority());
+    let url = Url::parse("http://example.com/tmp/foo").unwrap();
+    assert!(url.has_authority());
+}
+
+#[test]
+fn test_authority() {
+    let url = Url::parse("mailto:joe@example.com").unwrap();
+    assert_eq!(url.authority(), "");
+    let url = Url::parse("unix:/run/foo.socket").unwrap();
+    assert_eq!(url.authority(), "");
+    let url = Url::parse("file:///tmp/foo").unwrap();
+    assert_eq!(url.authority(), "");
+    let url = Url::parse("http://example.com/tmp/foo").unwrap();
+    assert_eq!(url.authority(), "example.com");
+    let url = Url::parse("ftp://127.0.0.1:21/").unwrap();
+    assert_eq!(url.authority(), "127.0.0.1");
+    let url = Url::parse("ftp://user@127.0.0.1:2121/").unwrap();
+    assert_eq!(url.authority(), "user@127.0.0.1:2121");
+    let url = Url::parse("https://:@example.com/").unwrap();
+    assert_eq!(url.authority(), "example.com");
+    let url = Url::parse("https://:password@[::1]:8080/").unwrap();
+    assert_eq!(url.authority(), ":password@[::1]:8080");
+    let url = Url::parse("gopher://user:@àlex.example.com:70").unwrap();
+    assert_eq!(url.authority(), "user@%C3%A0lex.example.com:70");
+    let url = Url::parse("irc://àlex:àlex@àlex.рф.example.com:6667/foo").unwrap();
+    assert_eq!(
+        url.authority(),
+        "%C3%A0lex:%C3%A0lex@%C3%A0lex.%D1%80%D1%84.example.com:6667"
+    );
+    let url = Url::parse("https://àlex:àlex@àlex.рф.example.com:443/foo").unwrap();
+    assert_eq!(
+        url.authority(),
+        "%C3%A0lex:%C3%A0lex@xn--lex-8ka.xn--p1ai.example.com"
+    );
+}