From 47af82d3b01dc9c98745ae5874c319e0dd53a971 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 23 Mar 2016 20:25:30 +0100 Subject: [PATCH] Rename non-relative to cannot-be-a-base, per upcoming spec change. See https://github.com/whatwg/url/issues/105 --- src/lib.rs | 54 ++++++++++++++++++++++------------------- src/parser.rs | 14 +++++------ src/percent_encoding.rs | 2 +- src/webidl.rs | 8 +++--- 4 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 26ceaf917..86e7516ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,10 +68,10 @@ assert!(issue_list_url.path_segments().map(|c| c.collect::>()) == Some(vec!["rust-lang", "rust", "issues"])); assert!(issue_list_url.query() == Some("labels=E-easy&state=open")); 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, 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(); -assert!(data_url.non_relative()); +assert!(data_url.cannot_be_a_base()); assert!(data_url.scheme() == "data"); assert!(data_url.path() == "text/plain,Hello"); assert!(data_url.path_segments().is_none()); @@ -250,9 +250,13 @@ impl Url { 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] - pub fn non_relative(&self) -> bool { + pub fn cannot_be_a_base(&self) -> bool { self.byte_at(self.path_start) != b'/' } @@ -285,7 +289,7 @@ impl Url { /// Non-ASCII domains are punycode-encoded per IDNA. /// 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. /// /// See also the `host` method. @@ -300,7 +304,7 @@ impl Url { /// Return the parsed representation of the host for this URL. /// 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. /// /// See also the `host_str` method. @@ -384,7 +388,7 @@ impl Url { /// Return the path for this URL, as a percent-encoded ASCII string. /// For relative URLs, this starts with a '/' slash /// 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 { match (self.query_start, self.fragment_start) { (None, None) => self.slice(self.path_start..), @@ -398,7 +402,7 @@ impl Url { /// If this URL is relative, return an iterator of '/' slash-separated path segments, /// 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> { let path = self.path(); if path.starts_with('/') { @@ -492,16 +496,16 @@ impl Url { (Some(i), _) | (None, Some(i)) => (i, self.slice(i..).to_owned()), (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()); self.serialization.truncate(self.path_start as usize); self.mutate(|parser| { - if non_relative { + if cannot_be_a_base { if path.starts_with('/') { parser.serialization.push_str("%2F"); - parser.parse_non_relative_path(&path[1..]); + parser.parse_cannot_be_a_base_path(&path[1..]); } else { - parser.parse_non_relative_path(path); + parser.parse_cannot_be_a_base_path(path); } } else { let mut has_host = true; // FIXME @@ -520,9 +524,9 @@ impl Url { /// 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<(), ()> { - if self.non_relative() { + if self.cannot_be_a_base() { return Err(()) } let last_slash; @@ -548,9 +552,9 @@ impl Url { /// 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<(), ()> { - if self.non_relative() { + if self.cannot_be_a_base() { return Err(()) } let after_path = match (self.query_start, self.fragment_start) { @@ -578,7 +582,7 @@ impl Url { /// 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`. pub fn set_port(&mut self, mut port: Option) -> Result<(), ()> { if !self.has_host() || self.scheme() == "file" { @@ -625,13 +629,13 @@ impl Url { /// 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`. /// /// Removing the host (calling this with `None`) /// will also remove any username, password, and port number. pub fn set_host(&mut self, host: Option<&str>) -> Result<(), ()> { - if self.non_relative() { + if self.cannot_be_a_base() { return Err(()) } @@ -695,11 +699,11 @@ impl Url { /// 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. pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ()> { - if self.non_relative() { + if self.cannot_be_a_base() { return Err(()) } @@ -713,7 +717,7 @@ impl Url { /// 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<(), ()> { if !self.has_host() { return Err(()) @@ -763,7 +767,7 @@ impl Url { /// 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<(), ()> { if !self.has_host() { return Err(()) @@ -801,7 +805,7 @@ impl Url { /// /// Do nothing and return `Err` if: /// * 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` pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> { self.set_scheme_internal(scheme, false) diff --git a/src/parser.rs b/src/parser.rs index 243d0d70a..c3f8c4553 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -50,7 +50,7 @@ simple_enum_error! { InvalidIpv6Address => "invalid IPv6 address", InvalidDomainCharacter => "invalid domain character", 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", } @@ -150,8 +150,8 @@ impl<'a> Parser<'a> { if let Some(base_url) = self.base_url { if input.starts_with("#") { 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 { let scheme_type = SchemeType::from(base_url.scheme()); if scheme_type.is_file() { @@ -210,8 +210,8 @@ impl<'a> Parser<'a> { if let Some(base_url) = self.base_url { if slashes_count < 2 && 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(); return self.parse_relative(input, scheme_type, base_url) } @@ -243,7 +243,7 @@ impl<'a> Parser<'a> { self.serialization.push('/'); self.parse_path(scheme_type, &mut false, path_start, &input[1..]) } 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, host_end, host, port, path_start, remaining) @@ -854,7 +854,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() { match c { '?' | '#' if self.context == Context::UrlParser => return &input[i..], diff --git a/src/percent_encoding.rs b/src/percent_encoding.rs index d9a265637..9f60f5c60 100644 --- a/src/percent_encoding.rs +++ b/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)] #[allow(non_camel_case_types)] pub struct SIMPLE_ENCODE_SET; diff --git a/src/webidl.rs b/src/webidl.rs index 22c734a64..4247427ce 100644 --- a/src/webidl.rs +++ b/src/webidl.rs @@ -91,7 +91,7 @@ impl WebIdl { /// Setter for https://url.spec.whatwg.org/#dom-url-host pub fn set_host(url: &mut Url, new_host: &str) { - if url.non_relative() { + if url.cannot_be_a_base() { return } let host; @@ -123,7 +123,7 @@ impl WebIdl { /// Setter for https://url.spec.whatwg.org/#dom-url-hostname pub fn set_hostname(url: &mut Url, new_hostname: &str) { - if url.non_relative() { + if url.cannot_be_a_base() { return } 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) { let result; { - // has_host implies !non_relative + // has_host implies !cannot_be_a_base let scheme = url.scheme(); if !url.has_host() || scheme == "file" { return @@ -167,7 +167,7 @@ impl WebIdl { /// Setter for https://url.spec.whatwg.org/#dom-url-pathname 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) } }