Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.0, rewrite the data structure and API #176

Merged
merged 89 commits into from Apr 20, 2016
Merged
Changes from 1 commit
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
83f4b9e
Split IDNA into a separate crate.
SimonSapin Mar 30, 2016
e0e60e9
IDNA: One test in the test harness per test case.
SimonSapin Mar 30, 2016
46acea9
Make it possible to define new encode sets in other crates.
SimonSapin Dec 4, 2015
87ee434
Define encode sets based on another set.
SimonSapin Dec 4, 2015
4ec32fa
Remove the HTTP_VALUE encode set. It can be defined in another crate.
SimonSapin Dec 4, 2015
9e759f1
Rewrite ALL THE THINGS!
SimonSapin Dec 9, 2015
2972218
Remove the dependency on uuid.
SimonSapin Feb 8, 2016
162e23f
Add URL slicing/indexing by component.
SimonSapin Feb 8, 2016
fa70482
Add stubs with partial implementation for the WebIDL API.
SimonSapin Feb 8, 2016
46d9fc9
Shorter Cargo.toml syntax.
SimonSapin Feb 8, 2016
b6686eb
serde_serialization -> serde
SimonSapin Feb 8, 2016
7517c8d
Make rustc-serialize an optional dependency.
SimonSapin Feb 8, 2016
7881aa5
Rename *{Start,End} posititons to {Before,After}*
SimonSapin Feb 9, 2016
a880bd3
Replace from_hex() with char::to_digit(16)
SimonSapin Feb 9, 2016
6db8b84
Make percent-decoding an iterator.
SimonSapin Feb 9, 2016
a3210b9
Make percent-encoding an iterator.
SimonSapin Feb 9, 2016
6fadafa
Add percent-encoding convienience wrappers.
SimonSapin Feb 9, 2016
1c9fb2f
Update tests from https://github.com/w3c/web-platform-tests/blob/mast…
SimonSapin Feb 10, 2016
f59870f
Remove Url::has_host
SimonSapin Feb 11, 2016
42b57d3
Remove unused ParseError variants
SimonSapin Feb 12, 2016
194da72
Make context a field of Parser.
SimonSapin Feb 11, 2016
31bde79
Remove the redundant is_relative field.
SimonSapin Feb 15, 2016
5364f2b
Add Url::domain and Url::ip_address
SimonSapin Feb 15, 2016
1afe54f
Implement ToSocketAddrs
SimonSapin Feb 15, 2016
21db81f
Remove Url::ip_address for now
SimonSapin Feb 15, 2016
1a22a90
Add Unicode and ASCII serializations of origins
SimonSapin Feb 16, 2016
8eba0ce
Test WebIdl::origin
SimonSapin Feb 16, 2016
44b601b
Add a fragment setter
SimonSapin Feb 11, 2016
0ac1ac5
Add a query setter.
SimonSapin Feb 12, 2016
ec1e55d
Make Url::parse_with usable. (EncodingOverride is private.)
SimonSapin Feb 19, 2016
0e5e27c
Add Origin::is_tuple
SimonSapin Feb 19, 2016
1813290
More consistent checks for URL with authority or path-only.
SimonSapin Feb 19, 2016
aaa1540
Re-export OpaqueOrigin. It is exposed publicly through Origin::Opaque
SimonSapin Feb 19, 2016
c9e687c
Add a scheme setter
SimonSapin Feb 19, 2016
0c30434
Add host setters.
SimonSapin Feb 19, 2016
f8f9176
More setters
SimonSapin Feb 23, 2016
5425385
Add a path setter
SimonSapin Feb 26, 2016
fc9a1db
Username and passowrd setters
SimonSapin Feb 26, 2016
8306485
More WebIDL implementations.
SimonSapin Feb 26, 2016
06f2faf
Port setters
SimonSapin Mar 1, 2016
a1f389f
All setters.
SimonSapin Mar 1, 2016
cb61d43
Replase set_ipv{4,6}_host with set_ip_host taking IpAddr.
SimonSapin Mar 23, 2016
450af0e
Maintain the invariant that an URL can not be both non-relative and s…
SimonSapin Mar 23, 2016
4ee7681
Add Url::into_string
SimonSapin Mar 23, 2016
9bf2c60
Rename non-relative to cannot-be-a-base, per upcoming spec change.
SimonSapin Mar 23, 2016
ca6a4ae
Remove some `unsafe` blocks.
SimonSapin Mar 23, 2016
6830dec
Back to the builder pattern after all.
SimonSapin Mar 24, 2016
b4bbaaa
Docs
SimonSapin Mar 24, 2016
ef0a1b2
Move webidl.rs to Servo.
SimonSapin Mar 25, 2016
d0c2bc2
One unit tests crate.
SimonSapin Mar 30, 2016
8813343
Percent-encoding yields `&str` instead of `char`.
SimonSapin Apr 1, 2016
988494d
Replace {lossy_,}utf8_percent_decode with percent_decode().decode_utf…
SimonSapin Apr 1, 2016
31cdce5
form_urlencoded::parse returns an iterator.
SimonSapin Apr 1, 2016
837a8da
Introduce "output encoding", per spec.
SimonSapin Apr 2, 2016
507ff3f
Self
SimonSapin Apr 2, 2016
8e6418a
Don’t take time to run 0 in-crate unit tests
SimonSapin Apr 2, 2016
d3e9824
Cow wrangling. (Reduce allocations/copying.)
SimonSapin Apr 2, 2016
bea7a48
form_urlencoded::Serializer is a "stateful" object.
SimonSapin Apr 2, 2016
6f716e1
Add Url::mutate_query_pairs
SimonSapin Apr 2, 2016
125cf96
Method chaining
SimonSapin Apr 2, 2016
2375850
Backport to Rust 1.7
SimonSapin Apr 2, 2016
6c6386d
Url::mutate_query_pairs return a value with Drop rather than take a c…
SimonSapin Apr 3, 2016
dd2d1ea
Rename append_pairs to append_pair_iter
SimonSapin Apr 3, 2016
224aee6
Add form_urlencoded::Parse::into_owned
SimonSapin Apr 8, 2016
f4bd6e5
Check invariants during tests.
SimonSapin Apr 4, 2016
0cd4d36
Rename test crates.
SimonSapin Apr 8, 2016
e8df8a3
Prepare for more than one kind of data-driven test.
SimonSapin Apr 8, 2016
8685112
Bring back urlutils.rs / webidl.rs after all
SimonSapin Apr 8, 2016
92eb5a6
Test harness for setters.
SimonSapin Apr 8, 2016
81779d5
Add protocol setter tests.
SimonSapin Apr 12, 2016
eb4d9b1
Username setter tests and fixes.
SimonSapin Apr 12, 2016
777413d
Password setter tests and fixes
SimonSapin Apr 12, 2016
42e608e
host setter tests and fixes
SimonSapin Apr 13, 2016
e65ece7
Add hostname setter tests
SimonSapin Apr 13, 2016
26bdb3a
Port setter tests and fixes
SimonSapin Apr 13, 2016
680d93c
pathname setter tests and fixes
SimonSapin Apr 13, 2016
de99ede
Add search setter tests
SimonSapin Apr 13, 2016
d6da85d
Add tests for hash setter.
SimonSapin Apr 13, 2016
1fdd019
Rename append_pair_iter to extend_pairs
SimonSapin Apr 19, 2016
8bc3285
Typo fix.
SimonSapin Apr 19, 2016
adba760
Copyright date
SimonSapin Apr 19, 2016
cd9fda8
Fix/clarify comments, and add a debug_assert!
SimonSapin Apr 19, 2016
806bab0
form_urlencoded::Parse::into_owned returns a dedicated type
SimonSapin Apr 19, 2016
9602247
Use an atomic counter rather than allocation to make opaque origin un…
SimonSapin Apr 19, 2016
3f92946
Fewer magic numbers.
SimonSapin Apr 20, 2016
e403579
More detailed error type for Url::set_host
SimonSapin Apr 20, 2016
f6996c8
Have a single `impl Url` block with public methods.
SimonSapin Apr 20, 2016
18c0806
1.0.0
SimonSapin Apr 20, 2016
4a59d93
Let’s not try to manually maintain a list of authors.
SimonSapin Apr 20, 2016
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

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

  • Loading branch information
SimonSapin committed Apr 17, 2016
commit 9bf2c60699a337d007cb002700259aa0c8f190b9
@@ -68,10 +68,10 @@ assert!(issue_list_url.path_segments().map(|c| c.collect::<Vec<_>>()) ==
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());
@@ -247,9 +247,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'/'
}

@@ -282,7 +286,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.
@@ -297,7 +301,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.
@@ -381,7 +385,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..),
@@ -395,7 +399,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<str::Split<char>> {
let path = self.path();
if path.starts_with('/') {
@@ -489,16 +493,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
@@ -517,9 +521,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;
@@ -545,9 +549,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) {
@@ -575,7 +579,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<u16>) -> Result<(), ()> {
if !self.has_host() || self.scheme() == "file" {
@@ -622,13 +626,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(())
}

@@ -692,11 +696,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(())
}

@@ -710,7 +714,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(())
@@ -760,7 +764,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(())
@@ -798,7 +802,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)
@@ -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",
}

@@ -154,8 +154,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() {
@@ -214,8 +214,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)
}
@@ -247,7 +247,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)
@@ -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() {
match c {
'?' | '#' if self.context == Context::UrlParser => return &input[i..],
@@ -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;
@@ -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)
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.