Skip to content

Commit 5e1be3f

Browse files
committed
Replace () error types in several functions.
This is an initial pass at servo#299. It does not change `ParseError` to the more idiomatic `Error` name, or change `with_default_port`'s return type.
1 parent 4e38c16 commit 5e1be3f

File tree

4 files changed

+78
-41
lines changed

4 files changed

+78
-41
lines changed

src/lib.rs

+21-21
Original file line numberDiff line numberDiff line change
@@ -1427,10 +1427,10 @@ impl Url {
14271427
/// # }
14281428
/// # run().unwrap();
14291429
/// ```
1430-
pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ()> {
1430+
pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ParseError> {
14311431
// has_host implies !cannot_be_a_base
14321432
if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
1433-
return Err(());
1433+
return Err(ParseError::EmptyHost);
14341434
}
14351435
if port.is_some() && port == parser::default_port(self.scheme()) {
14361436
port = None
@@ -1679,9 +1679,9 @@ impl Url {
16791679
/// # run().unwrap();
16801680
/// ```
16811681
///
1682-
pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ()> {
1682+
pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ParseError> {
16831683
if self.cannot_be_a_base() {
1684-
return Err(());
1684+
return Err(ParseError::SetHostOnCannotBeABaseUrl);
16851685
}
16861686

16871687
let address = match address {
@@ -1718,10 +1718,10 @@ impl Url {
17181718
/// # }
17191719
/// # run().unwrap();
17201720
/// ```
1721-
pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> {
1721+
pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ParseError> {
17221722
// has_host implies !cannot_be_a_base
17231723
if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
1724-
return Err(());
1724+
return Err(ParseError::EmptyHost);
17251725
}
17261726
if let Some(password) = password {
17271727
let host_and_after = self.slice(self.host_start..).to_owned();
@@ -1810,10 +1810,10 @@ impl Url {
18101810
/// # }
18111811
/// # run().unwrap();
18121812
/// ```
1813-
pub fn set_username(&mut self, username: &str) -> Result<(), ()> {
1813+
pub fn set_username(&mut self, username: &str) -> Result<(), ParseError> {
18141814
// has_host implies !cannot_be_a_base
18151815
if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
1816-
return Err(());
1816+
return Err(ParseError::EmptyHost);
18171817
}
18181818
let username_start = self.scheme_end + 3;
18191819
debug_assert!(self.slice(self.scheme_end..username_start) == "://");
@@ -1919,13 +1919,13 @@ impl Url {
19191919
/// # }
19201920
/// # run().unwrap();
19211921
/// ```
1922-
pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
1922+
pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ParseError> {
19231923
let mut parser = Parser::for_setter(String::new());
19241924
let remaining = parser.parse_scheme(parser::Input::new(scheme))?;
19251925
if !remaining.is_empty()
19261926
|| (!self.has_host() && SchemeType::from(&parser.serialization).is_special())
19271927
{
1928-
return Err(());
1928+
return Err(ParseError::InvalidScheme);
19291929
}
19301930
let old_scheme_end = self.scheme_end;
19311931
let new_scheme_end = to_u32(parser.serialization.len()).unwrap();
@@ -1964,7 +1964,7 @@ impl Url {
19641964
/// # if cfg!(unix) {
19651965
/// use url::Url;
19661966
///
1967-
/// # fn run() -> Result<(), ()> {
1967+
/// # fn run() -> Result<(), url::ParseError> {
19681968
/// let url = Url::from_file_path("/tmp/foo.txt")?;
19691969
/// assert_eq!(url.as_str(), "file:///tmp/foo.txt");
19701970
///
@@ -1979,7 +1979,7 @@ impl Url {
19791979
/// # }
19801980
/// ```
19811981
#[cfg(any(unix, windows, target_os = "redox"))]
1982-
pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
1982+
pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Url, ParseError> {
19831983
let mut serialization = "file://".to_owned();
19841984
let host_start = serialization.len() as u32;
19851985
let (host_end, host) = path_to_file_url_segments(path.as_ref(), &mut serialization)?;
@@ -2015,7 +2015,7 @@ impl Url {
20152015
/// Note that `std::path` does not consider trailing slashes significant
20162016
/// and usually does not include them (e.g. in `Path::parent()`).
20172017
#[cfg(any(unix, windows, target_os = "redox"))]
2018-
pub fn from_directory_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
2018+
pub fn from_directory_path<P: AsRef<Path>>(path: P) -> Result<Url, ParseError> {
20192019
let mut url = Url::from_file_path(path)?;
20202020
if !url.serialization.ends_with('/') {
20212021
url.serialization.push('/')
@@ -2124,26 +2124,26 @@ impl Url {
21242124
/// let path = url.to_file_path();
21252125
/// ```
21262126
///
2127-
/// Returns `Err` if the host is neither empty nor `"localhost"` (except on Windows, where
2127+
/// Returns `Err(ParseError::InvalidLocalPath)` if the host is neither empty nor `"localhost"` (except on Windows, where
21282128
/// `file:` URLs may have a non-local host),
21292129
/// or if `Path::new_opt()` returns `None`.
21302130
/// (That is, if the percent-decoded path contains a NUL byte or,
21312131
/// for a Windows path, is not UTF-8.)
21322132
#[inline]
21332133
#[cfg(any(unix, windows, target_os = "redox"))]
2134-
pub fn to_file_path(&self) -> Result<PathBuf, ()> {
2134+
pub fn to_file_path(&self) -> Result<PathBuf, ParseError> {
21352135
if let Some(segments) = self.path_segments() {
21362136
let host = match self.host() {
21372137
None | Some(Host::Domain("localhost")) => None,
21382138
Some(_) if cfg!(windows) && self.scheme() == "file" => {
21392139
Some(&self.serialization[self.host_start as usize..self.host_end as usize])
21402140
}
2141-
_ => return Err(()),
2141+
_ => return Err(ParseError::InvalidLocalPath),
21422142
};
21432143

21442144
return file_url_segments_to_pathbuf(host, segments);
21452145
}
2146-
Err(())
2146+
Err(ParseError::InvalidLocalPath)
21472147
}
21482148

21492149
// Private helper methods:
@@ -2293,10 +2293,10 @@ impl<'de> serde::Deserialize<'de> for Url {
22932293
fn path_to_file_url_segments(
22942294
path: &Path,
22952295
serialization: &mut String,
2296-
) -> Result<(u32, HostInternal), ()> {
2296+
) -> Result<(u32, HostInternal), ParseError> {
22972297
use std::os::unix::prelude::OsStrExt;
22982298
if !path.is_absolute() {
2299-
return Err(());
2299+
return Err(ParseError::PathNotAbsolute);
23002300
}
23012301
let host_end = to_u32(serialization.len()).unwrap();
23022302
let mut empty = true;
@@ -2378,12 +2378,12 @@ fn path_to_file_url_segments_windows(
23782378
fn file_url_segments_to_pathbuf(
23792379
host: Option<&str>,
23802380
segments: str::Split<char>,
2381-
) -> Result<PathBuf, ()> {
2381+
) -> Result<PathBuf, ParseError> {
23822382
use std::ffi::OsStr;
23832383
use std::os::unix::prelude::OsStrExt;
23842384

23852385
if host.is_some() {
2386-
return Err(());
2386+
return Err(ParseError::InvalidLocalPath);
23872387
}
23882388

23892389
let mut bytes = if cfg!(target_os = "redox") {

src/parser.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,16 @@ simple_enum_error! {
7272
EmptyHost => "empty host",
7373
IdnaError => "invalid international domain name",
7474
InvalidPort => "invalid port number",
75+
InvalidScheme => "invalid scheme",
7576
InvalidIpv4Address => "invalid IPv4 address",
7677
InvalidIpv6Address => "invalid IPv6 address",
7778
InvalidDomainCharacter => "invalid domain character",
7879
RelativeUrlWithoutBase => "relative URL without a base",
7980
RelativeUrlWithCannotBeABaseBase => "relative URL with a cannot-be-a-base base",
8081
SetHostOnCannotBeABaseUrl => "a cannot-be-a-base URL doesn’t have a host to set",
8182
Overflow => "URLs more than 4 GB are not supported",
83+
InvalidLocalPath => "the url is not a valid local path",
84+
PathNotAbsolute => "path component of url is not absolute",
8285
}
8386

8487
impl fmt::Display for ParseError {
@@ -357,9 +360,9 @@ impl<'a> Parser<'a> {
357360
}
358361
}
359362

360-
pub fn parse_scheme<'i>(&mut self, mut input: Input<'i>) -> Result<Input<'i>, ()> {
363+
pub fn parse_scheme<'i>(&mut self, mut input: Input<'i>) -> Result<Input<'i>, ParseError> {
361364
if input.is_empty() || !input.starts_with(ascii_alpha) {
362-
return Err(());
365+
return Err(ParseError::InvalidScheme);
363366
}
364367
debug_assert!(self.serialization.is_empty());
365368
while let Some(c) = input.next() {
@@ -370,7 +373,7 @@ impl<'a> Parser<'a> {
370373
':' => return Ok(input),
371374
_ => {
372375
self.serialization.clear();
373-
return Err(());
376+
return Err(ParseError::InvalidScheme);
374377
}
375378
}
376379
}
@@ -379,7 +382,7 @@ impl<'a> Parser<'a> {
379382
Ok(input)
380383
} else {
381384
self.serialization.clear();
382-
Err(())
385+
Err(ParseError::InvalidScheme)
383386
}
384387
}
385388

src/quirks.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub fn protocol(url: &Url) -> &str {
5656
}
5757

5858
/// Setter for https://url.spec.whatwg.org/#dom-url-protocol
59-
pub fn set_protocol(url: &mut Url, mut new_protocol: &str) -> Result<(), ()> {
59+
pub fn set_protocol(url: &mut Url, mut new_protocol: &str) -> Result<(), ParseError> {
6060
// The scheme state in the spec ignores everything after the first `:`,
6161
// but `set_scheme` errors if there is more.
6262
if let Some(position) = new_protocol.find(':') {
@@ -72,7 +72,7 @@ pub fn username(url: &Url) -> &str {
7272
}
7373

7474
/// Setter for https://url.spec.whatwg.org/#dom-url-username
75-
pub fn set_username(url: &mut Url, new_username: &str) -> Result<(), ()> {
75+
pub fn set_username(url: &mut Url, new_username: &str) -> Result<(), ParseError> {
7676
url.set_username(new_username)
7777
}
7878

@@ -83,7 +83,7 @@ pub fn password(url: &Url) -> &str {
8383
}
8484

8585
/// Setter for https://url.spec.whatwg.org/#dom-url-password
86-
pub fn set_password(url: &mut Url, new_password: &str) -> Result<(), ()> {
86+
pub fn set_password(url: &mut Url, new_password: &str) -> Result<(), ParseError> {
8787
url.set_password(if new_password.is_empty() {
8888
None
8989
} else {

tests/unit.rs

+47-13
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::borrow::Cow;
1515
use std::cell::{Cell, RefCell};
1616
use std::net::{Ipv4Addr, Ipv6Addr};
1717
use std::path::{Path, PathBuf};
18-
use url::{form_urlencoded, Host, Url};
18+
use url::{form_urlencoded, Host, ParseError, Url};
1919

2020
#[test]
2121
fn size() {
@@ -38,14 +38,32 @@ macro_rules! assert_from_file_path {
3838
#[test]
3939
fn new_file_paths() {
4040
if cfg!(unix) {
41-
assert_eq!(Url::from_file_path(Path::new("relative")), Err(()));
42-
assert_eq!(Url::from_file_path(Path::new("../relative")), Err(()));
41+
assert_eq!(
42+
Url::from_file_path(Path::new("relative")),
43+
Err(ParseError::PathNotAbsolute)
44+
);
45+
assert_eq!(
46+
Url::from_file_path(Path::new("../relative")),
47+
Err(ParseError::PathNotAbsolute)
48+
);
4349
}
4450
if cfg!(windows) {
45-
assert_eq!(Url::from_file_path(Path::new("relative")), Err(()));
46-
assert_eq!(Url::from_file_path(Path::new(r"..\relative")), Err(()));
47-
assert_eq!(Url::from_file_path(Path::new(r"\drive-relative")), Err(()));
48-
assert_eq!(Url::from_file_path(Path::new(r"\\ucn\")), Err(()));
51+
assert_eq!(
52+
Url::from_file_path(Path::new("relative")),
53+
Err(ParseError::PathNotAbsolute)
54+
);
55+
assert_eq!(
56+
Url::from_file_path(Path::new(r"..\relative")),
57+
Err(ParseError::PathNotAbsolute)
58+
);
59+
assert_eq!(
60+
Url::from_file_path(Path::new(r"\drive-relative")),
61+
Err(ParseError::PathNotAbsolute)
62+
);
63+
assert_eq!(
64+
Url::from_file_path(Path::new(r"\\ucn\")),
65+
Err(ParseError::PathNotAbsolute)
66+
);
4967
}
5068

5169
if cfg!(unix) {
@@ -90,22 +108,38 @@ fn new_path_windows_fun() {
90108

91109
#[test]
92110
fn new_directory_paths() {
111+
use url::ParseError;
93112
if cfg!(unix) {
94-
assert_eq!(Url::from_directory_path(Path::new("relative")), Err(()));
95-
assert_eq!(Url::from_directory_path(Path::new("../relative")), Err(()));
113+
assert_eq!(
114+
Url::from_directory_path(Path::new("relative")),
115+
Err(ParseError::PathNotAbsolute)
116+
);
117+
assert_eq!(
118+
Url::from_directory_path(Path::new("../relative")),
119+
Err(ParseError::PathNotAbsolute)
120+
);
96121

97122
let url = Url::from_directory_path(Path::new("/foo/bar")).unwrap();
98123
assert_eq!(url.host(), None);
99124
assert_eq!(url.path(), "/foo/bar/");
100125
}
101126
if cfg!(windows) {
102-
assert_eq!(Url::from_directory_path(Path::new("relative")), Err(()));
103-
assert_eq!(Url::from_directory_path(Path::new(r"..\relative")), Err(()));
127+
assert_eq!(
128+
Url::from_directory_path(Path::new("relative")),
129+
Err(ParseError::PathNotAbsolute)
130+
);
131+
assert_eq!(
132+
Url::from_directory_path(Path::new(r"..\relative")),
133+
Err(ParseError::PathNotAbsolute)
134+
);
104135
assert_eq!(
105136
Url::from_directory_path(Path::new(r"\drive-relative")),
106-
Err(())
137+
Err(ParseError::PathNotAbsolute)
138+
);
139+
assert_eq!(
140+
Url::from_directory_path(Path::new(r"\\ucn\")),
141+
Err(ParseError::PathNotAbsolute)
107142
);
108-
assert_eq!(Url::from_directory_path(Path::new(r"\\ucn\")), Err(()));
109143

110144
let url = Url::from_directory_path(Path::new(r"C:\foo\bar")).unwrap();
111145
assert_eq!(url.host(), None);

0 commit comments

Comments
 (0)