Просмотр исходного кода

Rename non-relative to cannot-be-a-base, per upcoming spec change.

See https://github.com/whatwg/url/issues/105
Simon Sapin 10 лет назад
Родитель
Сommit
9bf2c60699
4 измененных файлов с 41 добавлено и 37 удалено
  1. 29 25
      src/lib.rs
  2. 7 7
      src/parser.rs
  3. 1 1
      src/percent_encoding.rs
  4. 4 4
      src/webidl.rs

+ 29 - 25
src/lib.rs

@@ -68,10 +68,10 @@ assert!(issue_list_url.path_segments().map(|c| c.collect::<Vec<_>>()) ==
         Some(vec!["rust-lang", "rust", "issues"]));
         Some(vec!["rust-lang", "rust", "issues"]));
 assert!(issue_list_url.query() == Some("labels=E-easy&state=open"));
 assert!(issue_list_url.query() == Some("labels=E-easy&state=open"));
 assert!(issue_list_url.fragment() == None);
 assert!(issue_list_url.fragment() == None);
-assert!(!issue_list_url.non_relative());
+assert!(!issue_list_url.cannot_be_a_base());
 ```
 ```
 
 
-Some URLs are said to be "non-relative":
+Some URLs are said to be *cannot-be-a-base*:
 they don’t have a username, password, host, or port,
 they don’t have a username, password, host, or port,
 and their "path" is an arbitrary string rather than slash-separated segments:
 and their "path" is an arbitrary string rather than slash-separated segments:
 
 
@@ -80,7 +80,7 @@ use url::Url;
 
 
 let data_url = Url::parse("data:text/plain,Hello?World#").unwrap();
 let data_url = Url::parse("data:text/plain,Hello?World#").unwrap();
 
 
-assert!(data_url.non_relative());
+assert!(data_url.cannot_be_a_base());
 assert!(data_url.scheme() == "data");
 assert!(data_url.scheme() == "data");
 assert!(data_url.path() == "text/plain,Hello");
 assert!(data_url.path() == "text/plain,Hello");
 assert!(data_url.path_segments().is_none());
 assert!(data_url.path_segments().is_none());
@@ -247,9 +247,13 @@ impl Url {
         self.slice(self.scheme_end + 1 ..).starts_with("//")
         self.slice(self.scheme_end + 1 ..).starts_with("//")
     }
     }
 
 
-    /// Return whether this URL is non-relative (typical of e.g. `data:` and `mailto:` URLs.)
+    /// 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.
+    ///
+    /// This is the case if the scheme and `:` delimiter are not followed by a `/` slash,
+    /// as is typically the case of `data:` and `mailto:` URLs.
     #[inline]
     #[inline]
-    pub fn non_relative(&self) -> bool {
+    pub fn cannot_be_a_base(&self) -> bool {
         self.byte_at(self.path_start) != b'/'
         self.byte_at(self.path_start) != b'/'
     }
     }
 
 
@@ -282,7 +286,7 @@ impl Url {
     /// Non-ASCII domains are punycode-encoded per IDNA.
     /// Non-ASCII domains are punycode-encoded per IDNA.
     /// IPv6 addresses are given between `[` and `]` brackets.
     /// IPv6 addresses are given between `[` and `]` brackets.
     ///
     ///
-    /// Non-relative URLs (typical of `data:` and `mailto:`) and some `file:` URLs
+    /// Cannot-be-a-base URLs (typical of `data:` and `mailto:`) and some `file:` URLs
     /// don’t have a host.
     /// don’t have a host.
     ///
     ///
     /// See also the `host` method.
     /// See also the `host` method.
@@ -297,7 +301,7 @@ impl Url {
     /// Return the parsed representation of the host for this URL.
     /// Return the parsed representation of the host for this URL.
     /// Non-ASCII domain labels are punycode-encoded per IDNA.
     /// Non-ASCII domain labels are punycode-encoded per IDNA.
     ///
     ///
-    /// Non-relative URLs (typical of `data:` and `mailto:`) and some `file:` URLs
+    /// Cannot-be-a-base URLs (typical of `data:` and `mailto:`) and some `file:` URLs
     /// don’t have a host.
     /// don’t have a host.
     ///
     ///
     /// See also the `host_str` method.
     /// See also the `host_str` method.
@@ -381,7 +385,7 @@ impl Url {
     /// Return the path for this URL, as a percent-encoded ASCII string.
     /// Return the path for this URL, as a percent-encoded ASCII string.
     /// For relative URLs, this starts with a '/' slash
     /// For relative URLs, this starts with a '/' slash
     /// and continues with slash-separated path segments.
     /// and continues with slash-separated path segments.
-    /// For non-relative URLs, this is an arbitrary string that doesn’t start with '/'.
+    /// For cannot-be-a-base URLs, this is an arbitrary string that doesn’t start with '/'.
     pub fn path(&self) -> &str {
     pub fn path(&self) -> &str {
         match (self.query_start, self.fragment_start) {
         match (self.query_start, self.fragment_start) {
             (None, None) => self.slice(self.path_start..),
             (None, None) => self.slice(self.path_start..),
@@ -395,7 +399,7 @@ impl Url {
     /// If this URL is relative, return an iterator of '/' slash-separated path segments,
     /// If this URL is relative, return an iterator of '/' slash-separated path segments,
     /// each as a percent-encoded ASCII string.
     /// each as a percent-encoded ASCII string.
     ///
     ///
-    /// Return `None` for non-relative URLs, or an iterator of at least one string.
+    /// Return `None` for cannot-be-a-base URLs, or an iterator of at least one string.
     pub fn path_segments(&self) -> Option<str::Split<char>> {
     pub fn path_segments(&self) -> Option<str::Split<char>> {
         let path = self.path();
         let path = self.path();
         if path.starts_with('/') {
         if path.starts_with('/') {
@@ -489,16 +493,16 @@ impl Url {
             (Some(i), _) | (None, Some(i)) => (i, self.slice(i..).to_owned()),
             (Some(i), _) | (None, Some(i)) => (i, self.slice(i..).to_owned()),
             (None, None) => (to_u32(self.serialization.len()).unwrap(), String::new())
             (None, None) => (to_u32(self.serialization.len()).unwrap(), String::new())
         };
         };
-        let non_relative = self.non_relative();
+        let cannot_be_a_base = self.cannot_be_a_base();
         let scheme_type = SchemeType::from(self.scheme());
         let scheme_type = SchemeType::from(self.scheme());
         self.serialization.truncate(self.path_start as usize);
         self.serialization.truncate(self.path_start as usize);
         self.mutate(|parser| {
         self.mutate(|parser| {
-            if non_relative {
+            if cannot_be_a_base {
                 if path.starts_with('/') {
                 if path.starts_with('/') {
                     parser.serialization.push_str("%2F");
                     parser.serialization.push_str("%2F");
-                    parser.parse_non_relative_path(&path[1..]);
+                    parser.parse_cannot_be_a_base_path(&path[1..]);
                 } else {
                 } else {
-                    parser.parse_non_relative_path(path);
+                    parser.parse_cannot_be_a_base_path(path);
                 }
                 }
             } else {
             } else {
                 let mut has_host = true;  // FIXME
                 let mut has_host = true;  // FIXME
@@ -517,9 +521,9 @@ impl Url {
 
 
     /// Remove the last segment of this URL’s path.
     /// Remove the last segment of this URL’s path.
     ///
     ///
-    /// If this URL is non-relative, do nothing and return `Err`.
+    /// If this URL is cannot-be-a-base, do nothing and return `Err`.
     pub fn pop_path_segment(&mut self) -> Result<(), ()> {
     pub fn pop_path_segment(&mut self) -> Result<(), ()> {
-        if self.non_relative() {
+        if self.cannot_be_a_base() {
             return Err(())
             return Err(())
         }
         }
         let last_slash;
         let last_slash;
@@ -545,9 +549,9 @@ impl Url {
 
 
     /// Add a segment at the end of this URL’s path.
     /// Add a segment at the end of this URL’s path.
     ///
     ///
-    /// If this URL is non-relative, do nothing and return `Err`.
+    /// If this URL is cannot-be-a-base, do nothing and return `Err`.
     pub fn push_path_segment(&mut self, segment: &str) -> Result<(), ()> {
     pub fn push_path_segment(&mut self, segment: &str) -> Result<(), ()> {
-        if self.non_relative() {
+        if self.cannot_be_a_base() {
             return Err(())
             return Err(())
         }
         }
         let after_path = match (self.query_start, self.fragment_start) {
         let after_path = match (self.query_start, self.fragment_start) {
@@ -575,7 +579,7 @@ impl Url {
 
 
     /// Change this URL’s port number.
     /// Change this URL’s port number.
     ///
     ///
-    /// If this URL is non-relative, does not have a host, or has the `file` scheme;
+    /// If this URL is cannot-be-a-base, does not have a host, or has the `file` scheme;
     /// do nothing and return `Err`.
     /// do nothing and return `Err`.
     pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ()> {
     pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ()> {
         if !self.has_host() || self.scheme() == "file" {
         if !self.has_host() || self.scheme() == "file" {
@@ -622,13 +626,13 @@ impl Url {
 
 
     /// Change this URL’s host.
     /// Change this URL’s host.
     ///
     ///
-    /// If this URL is non-relative or there is an error parsing the given `host`,
+    /// If this URL is cannot-be-a-base or there is an error parsing the given `host`,
     /// do nothing and return `Err`.
     /// do nothing and return `Err`.
     ///
     ///
     /// Removing the host (calling this with `None`)
     /// Removing the host (calling this with `None`)
     /// will also remove any username, password, and port number.
     /// will also remove any username, password, and port number.
     pub fn set_host(&mut self, host: Option<&str>) -> Result<(), ()> {
     pub fn set_host(&mut self, host: Option<&str>) -> Result<(), ()> {
-        if self.non_relative() {
+        if self.cannot_be_a_base() {
             return Err(())
             return Err(())
         }
         }
 
 
@@ -692,11 +696,11 @@ impl Url {
 
 
     /// Change this URL’s host to the given IP address.
     /// Change this URL’s host to the given IP address.
     ///
     ///
-    /// If this URL is non-relative, do nothing and return `Err`.
+    /// If this URL is cannot-be-a-base, do nothing and return `Err`.
     ///
     ///
     /// Compared to `Url::set_host`, this skips the host parser.
     /// Compared to `Url::set_host`, this skips the host parser.
     pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ()> {
     pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ()> {
-        if self.non_relative() {
+        if self.cannot_be_a_base() {
             return Err(())
             return Err(())
         }
         }
 
 
@@ -710,7 +714,7 @@ impl Url {
 
 
     /// Change this URL’s password.
     /// Change this URL’s password.
     ///
     ///
-    /// If this URL is non-relative or does not have a host, do nothing and return `Err`.
+    /// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
     pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> {
     pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> {
         if !self.has_host() {
         if !self.has_host() {
             return Err(())
             return Err(())
@@ -760,7 +764,7 @@ impl Url {
 
 
     /// Change this URL’s username.
     /// Change this URL’s username.
     ///
     ///
-    /// If this URL is non-relative or does not have a host, do nothing and return `Err`.
+    /// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
     pub fn set_username(&mut self, username: &str) -> Result<(), ()> {
     pub fn set_username(&mut self, username: &str) -> Result<(), ()> {
         if !self.has_host() {
         if !self.has_host() {
             return Err(())
             return Err(())
@@ -798,7 +802,7 @@ impl Url {
     ///
     ///
     /// Do nothing and return `Err` if:
     /// Do nothing and return `Err` if:
     /// * The new scheme is not in `[a-zA-Z][a-zA-Z0-9+.-]+`
     /// * The new scheme is not in `[a-zA-Z][a-zA-Z0-9+.-]+`
-    /// * This URL is non-relative and the new scheme is one of
+    /// * This URL is cannot-be-a-base and the new scheme is one of
     ///   `http`, `https`, `ws`, `wss`, `ftp`, or `gopher`
     ///   `http`, `https`, `ws`, `wss`, `ftp`, or `gopher`
     pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
     pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
         self.set_scheme_internal(scheme, false)
         self.set_scheme_internal(scheme, false)

+ 7 - 7
src/parser.rs

@@ -50,7 +50,7 @@ simple_enum_error! {
     InvalidIpv6Address => "invalid IPv6 address",
     InvalidIpv6Address => "invalid IPv6 address",
     InvalidDomainCharacter => "invalid domain character",
     InvalidDomainCharacter => "invalid domain character",
     RelativeUrlWithoutBase => "relative URL without a base",
     RelativeUrlWithoutBase => "relative URL without a base",
-    RelativeUrlWithNonRelativeBase => "relative URL with a non-relative base",
+    RelativeUrlWithCannotBeABaseBase => "relative URL with a cannot-be-a-base base",
     Overflow => "URLs more than 4 GB are not supported",
     Overflow => "URLs more than 4 GB are not supported",
 }
 }
 
 
@@ -154,8 +154,8 @@ impl<'a> Parser<'a> {
         if let Some(base_url) = self.base_url {
         if let Some(base_url) = self.base_url {
             if input.starts_with("#") {
             if input.starts_with("#") {
                 self.fragment_only(base_url, input)
                 self.fragment_only(base_url, input)
-            } else if base_url.non_relative() {
-                Err(ParseError::RelativeUrlWithNonRelativeBase)
+            } else if base_url.cannot_be_a_base() {
+                Err(ParseError::RelativeUrlWithCannotBeABaseBase)
             } else {
             } else {
                 let scheme_type = SchemeType::from(base_url.scheme());
                 let scheme_type = SchemeType::from(base_url.scheme());
                 if scheme_type.is_file() {
                 if scheme_type.is_file() {
@@ -214,8 +214,8 @@ impl<'a> Parser<'a> {
                 if let Some(base_url) = self.base_url {
                 if let Some(base_url) = self.base_url {
                     if slashes_count < 2 &&
                     if slashes_count < 2 &&
                             base_url.scheme() == &self.serialization[..scheme_end as usize] {
                             base_url.scheme() == &self.serialization[..scheme_end as usize] {
-                        // Non-relative URLs only happen with "not special" schemes.
-                        debug_assert!(!base_url.non_relative());
+                        // "Cannot-be-a-base" URLs only happen with "not special" schemes.
+                        debug_assert!(!base_url.cannot_be_a_base());
                         self.serialization.clear();
                         self.serialization.clear();
                         return self.parse_relative(input, scheme_type, base_url)
                         return self.parse_relative(input, scheme_type, base_url)
                     }
                     }
@@ -247,7 +247,7 @@ impl<'a> Parser<'a> {
             self.serialization.push('/');
             self.serialization.push('/');
             self.parse_path(scheme_type, &mut false, path_start, &input[1..])
             self.parse_path(scheme_type, &mut false, path_start, &input[1..])
         } else {
         } else {
-            self.parse_non_relative_path(input)
+            self.parse_cannot_be_a_base_path(input)
         };
         };
         self.with_query_and_fragment(scheme_end, username_end, host_start,
         self.with_query_and_fragment(scheme_end, username_end, host_start,
                                      host_end, host, port, path_start, remaining)
                                      host_end, host, port, path_start, remaining)
@@ -858,7 +858,7 @@ impl<'a> Parser<'a> {
 
 
     }
     }
 
 
-    pub fn parse_non_relative_path<'i>(&mut self, input: &'i str) -> &'i str {
+    pub fn parse_cannot_be_a_base_path<'i>(&mut self, input: &'i str) -> &'i str {
         for (i, c, next_i) in input.char_ranges() {
         for (i, c, next_i) in input.char_ranges() {
             match c {
             match c {
                 '?' | '#' if self.context == Context::UrlParser => return &input[i..],
                 '?' | '#' if self.context == Context::UrlParser => return &input[i..],

+ 1 - 1
src/percent_encoding.rs

@@ -74,7 +74,7 @@ macro_rules! define_encode_set {
     }
     }
 }
 }
 
 
-/// This encode set is used for fragment identifier and non-relative scheme data.
+/// This encode set is used for the path of cannot-be-a-base URLs.
 #[derive(Copy, Clone)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
 #[allow(non_camel_case_types)]
 pub struct SIMPLE_ENCODE_SET;
 pub struct SIMPLE_ENCODE_SET;

+ 4 - 4
src/webidl.rs

@@ -91,7 +91,7 @@ impl WebIdl {
 
 
     /// Setter for https://url.spec.whatwg.org/#dom-url-host
     /// Setter for https://url.spec.whatwg.org/#dom-url-host
     pub fn set_host(url: &mut Url, new_host: &str) {
     pub fn set_host(url: &mut Url, new_host: &str) {
-        if url.non_relative() {
+        if url.cannot_be_a_base() {
             return
             return
         }
         }
         let host;
         let host;
@@ -123,7 +123,7 @@ impl WebIdl {
 
 
     /// Setter for https://url.spec.whatwg.org/#dom-url-hostname
     /// Setter for https://url.spec.whatwg.org/#dom-url-hostname
     pub fn set_hostname(url: &mut Url, new_hostname: &str) {
     pub fn set_hostname(url: &mut Url, new_hostname: &str) {
-        if url.non_relative() {
+        if url.cannot_be_a_base() {
             return
             return
         }
         }
         let result = Parser::parse_host(new_hostname, SchemeType::from(url.scheme()), |_| ());
         let result = Parser::parse_host(new_hostname, SchemeType::from(url.scheme()), |_| ());
@@ -147,7 +147,7 @@ impl WebIdl {
     pub fn set_port(url: &mut Url, new_port: &str) {
     pub fn set_port(url: &mut Url, new_port: &str) {
         let result;
         let result;
         {
         {
-            // has_host implies !non_relative
+            // has_host implies !cannot_be_a_base
             let scheme = url.scheme();
             let scheme = url.scheme();
             if !url.has_host() || scheme == "file" {
             if !url.has_host() || scheme == "file" {
                 return
                 return
@@ -167,7 +167,7 @@ impl WebIdl {
 
 
     /// Setter for https://url.spec.whatwg.org/#dom-url-pathname
     /// Setter for https://url.spec.whatwg.org/#dom-url-pathname
     pub fn set_pathname(url: &mut Url, new_pathname: &str) {
     pub fn set_pathname(url: &mut Url, new_pathname: &str) {
-        if !url.non_relative() {
+        if !url.cannot_be_a_base() {
             url.set_path(new_pathname)
             url.set_path(new_pathname)
         }
         }
     }
     }