|
|
@@ -5,15 +5,7 @@
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
// except according to those terms.
|
|
|
-pub use ParseError::{
|
|
|
- EmptyHost,InvalidScheme,InvalidPort,InvalidIpv6Address,InvalidDomainCharacter,
|
|
|
- InvalidCharacter,InvalidBackslash,InvalidPercentEncoded,InvalidAtSymbolInUser,
|
|
|
- ExpectedTwoSlashes,ExpectedInitialSlash,NonUrlCodePoint,RelativeUrlWithScheme,
|
|
|
- RelativeUrlWithoutBase,RelativeUrlWithNonRelativeBase,
|
|
|
- NonAsciiDomainsNotSupportedYet
|
|
|
-};
|
|
|
|
|
|
-pub use self::Context::{SetterContext,UrlParserContext};
|
|
|
use std::ascii::AsciiExt;
|
|
|
use std::error::Error;
|
|
|
use std::fmt::{mod, Formatter, Show};
|
|
|
@@ -21,11 +13,7 @@ use std::str::CharRange;
|
|
|
|
|
|
use encoding;
|
|
|
|
|
|
-use super::{
|
|
|
- UrlParser, Url, RelativeSchemeData, NonRelativeSchemeData, Host, Domain,
|
|
|
- SchemeType, FileLikeRelativeScheme, RelativeScheme, NonRelativeScheme,
|
|
|
- UrlRelativeSchemeData,
|
|
|
-};
|
|
|
+use super::{UrlParser, Url, SchemeData, RelativeSchemeData, Host, SchemeType};
|
|
|
use percent_encoding::{
|
|
|
utf8_percent_encode_to, percent_encode,
|
|
|
SIMPLE_ENCODE_SET, DEFAULT_ENCODE_SET, USERINFO_ENCODE_SET, QUERY_ENCODE_SET
|
|
|
@@ -108,59 +96,59 @@ pub type ErrorHandler = fn(reason: ParseError) -> ParseResult<()>;
|
|
|
|
|
|
#[deriving(PartialEq, Eq)]
|
|
|
pub enum Context {
|
|
|
- UrlParserContext,
|
|
|
- SetterContext,
|
|
|
+ UrlParser,
|
|
|
+ Setter,
|
|
|
}
|
|
|
|
|
|
|
|
|
pub fn parse_url(input: &str, parser: &UrlParser) -> ParseResult<Url> {
|
|
|
let input = input.trim_chars([' ', '\t', '\n', '\r', '\x0C'].as_slice());
|
|
|
- let (scheme, remaining) = match parse_scheme(input, UrlParserContext) {
|
|
|
+ let (scheme, remaining) = match parse_scheme(input, Context::UrlParser) {
|
|
|
Some((scheme, remaining)) => (scheme, remaining),
|
|
|
// No-scheme state
|
|
|
None => return match parser.base_url {
|
|
|
- Some(&Url { ref scheme, scheme_data: RelativeSchemeData(ref base),
|
|
|
+ Some(&Url { ref scheme, scheme_data: SchemeData::Relative(ref base),
|
|
|
ref query, .. }) => {
|
|
|
let scheme_type = parser.get_scheme_type(scheme.as_slice());
|
|
|
parse_relative_url(input, scheme.clone(), scheme_type, base, query, parser)
|
|
|
},
|
|
|
- Some(_) => Err(RelativeUrlWithNonRelativeBase),
|
|
|
- None => Err(RelativeUrlWithoutBase),
|
|
|
+ Some(_) => Err(ParseError::RelativeUrlWithNonRelativeBase),
|
|
|
+ None => Err(ParseError::RelativeUrlWithoutBase),
|
|
|
},
|
|
|
};
|
|
|
let scheme_type = parser.get_scheme_type(scheme.as_slice());
|
|
|
match scheme_type {
|
|
|
- FileLikeRelativeScheme => {
|
|
|
+ SchemeType::FileLike => {
|
|
|
// Relative state?
|
|
|
match parser.base_url {
|
|
|
- Some(&Url { scheme: ref base_scheme, scheme_data: RelativeSchemeData(ref base),
|
|
|
+ Some(&Url { scheme: ref base_scheme, scheme_data: SchemeData::Relative(ref base),
|
|
|
ref query, .. })
|
|
|
if scheme == *base_scheme => {
|
|
|
parse_relative_url(remaining, scheme, scheme_type, base, query, parser)
|
|
|
},
|
|
|
// FIXME: Should not have to use a made-up base URL.
|
|
|
- _ => parse_relative_url(remaining, scheme, scheme_type, &UrlRelativeSchemeData {
|
|
|
- username: String::new(), password: None, host: Domain(String::new()),
|
|
|
+ _ => parse_relative_url(remaining, scheme, scheme_type, &RelativeSchemeData {
|
|
|
+ username: String::new(), password: None, host: Host::Domain(String::new()),
|
|
|
port: None, default_port: None, path: Vec::new()
|
|
|
}, &None, parser)
|
|
|
}
|
|
|
},
|
|
|
- RelativeScheme(..) => {
|
|
|
+ SchemeType::Relative(..) => {
|
|
|
match parser.base_url {
|
|
|
- Some(&Url { scheme: ref base_scheme, scheme_data: RelativeSchemeData(ref base),
|
|
|
+ Some(&Url { scheme: ref base_scheme, scheme_data: SchemeData::Relative(ref base),
|
|
|
ref query, .. })
|
|
|
if scheme == *base_scheme && !remaining.starts_with("//") => {
|
|
|
- try!(parser.parse_error(RelativeUrlWithScheme));
|
|
|
+ try!(parser.parse_error(ParseError::RelativeUrlWithScheme));
|
|
|
parse_relative_url(remaining, scheme, scheme_type, base, query, parser)
|
|
|
},
|
|
|
_ => parse_absolute_url(scheme, scheme_type, remaining, parser),
|
|
|
}
|
|
|
},
|
|
|
- NonRelativeScheme => {
|
|
|
+ SchemeType::NonRelative => {
|
|
|
// Scheme data state
|
|
|
let (scheme_data, remaining) = try!(parse_scheme_data(remaining, parser));
|
|
|
let (query, fragment) = try!(parse_query_and_fragment(remaining, parser));
|
|
|
- Ok(Url { scheme: scheme, scheme_data: NonRelativeSchemeData(scheme_data),
|
|
|
+ Ok(Url { scheme: scheme, scheme_data: SchemeData::NonRelative(scheme_data),
|
|
|
query: query, fragment: fragment })
|
|
|
}
|
|
|
}
|
|
|
@@ -183,8 +171,8 @@ pub fn parse_scheme<'a>(input: &'a str, context: Context) -> Option<(String, &'a
|
|
|
}
|
|
|
// EOF before ':'
|
|
|
match context {
|
|
|
- SetterContext => Some((input.to_ascii_lower(), "")),
|
|
|
- UrlParserContext => None
|
|
|
+ Context::Setter => Some((input.to_ascii_lower(), "")),
|
|
|
+ Context::UrlParser => None
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -198,8 +186,8 @@ fn parse_absolute_url<'a>(scheme: String, scheme_type: SchemeType,
|
|
|
// Host state
|
|
|
let (host, port, default_port, remaining) = try!(parse_host(remaining, scheme_type, parser));
|
|
|
let (path, remaining) = try!(parse_path_start(
|
|
|
- remaining, UrlParserContext, scheme_type, parser));
|
|
|
- let scheme_data = RelativeSchemeData(UrlRelativeSchemeData {
|
|
|
+ remaining, Context::UrlParser, scheme_type, parser));
|
|
|
+ let scheme_data = SchemeData::Relative(RelativeSchemeData {
|
|
|
username: username, password: password,
|
|
|
host: host, port: port, default_port: default_port,
|
|
|
path: path });
|
|
|
@@ -209,19 +197,21 @@ fn parse_absolute_url<'a>(scheme: String, scheme_type: SchemeType,
|
|
|
|
|
|
|
|
|
fn parse_relative_url<'a>(input: &'a str, scheme: String, scheme_type: SchemeType,
|
|
|
- base: &UrlRelativeSchemeData, base_query: &Option<String>,
|
|
|
+ base: &RelativeSchemeData, base_query: &Option<String>,
|
|
|
parser: &UrlParser)
|
|
|
-> ParseResult<Url> {
|
|
|
if input.is_empty() {
|
|
|
- return Ok(Url { scheme: scheme, scheme_data: RelativeSchemeData(base.clone()),
|
|
|
+ return Ok(Url { scheme: scheme, scheme_data: SchemeData::Relative(base.clone()),
|
|
|
query: base_query.clone(), fragment: None })
|
|
|
}
|
|
|
match input.char_at(0) {
|
|
|
'/' | '\\' => {
|
|
|
// Relative slash state
|
|
|
if input.len() > 1 && is_match!(input.char_at(1), '/' | '\\') {
|
|
|
- if input.char_at(1) == '\\' { try!(parser.parse_error(InvalidBackslash)) }
|
|
|
- if scheme_type == FileLikeRelativeScheme {
|
|
|
+ if input.char_at(1) == '\\' {
|
|
|
+ try!(parser.parse_error(ParseError::InvalidBackslash))
|
|
|
+ }
|
|
|
+ if scheme_type == SchemeType::FileLike {
|
|
|
// File host state
|
|
|
let remaining = input.slice_from(2);
|
|
|
let (host, remaining) = if remaining.len() >= 2
|
|
|
@@ -232,13 +222,13 @@ fn parse_relative_url<'a>(input: &'a str, scheme: String, scheme_type: SchemeTyp
|
|
|
'/' | '\\' | '?' | '#'))
|
|
|
{
|
|
|
// Windows drive letter quirk
|
|
|
- (Domain(String::new()), remaining)
|
|
|
+ (Host::Domain(String::new()), remaining)
|
|
|
} else {
|
|
|
try!(parse_file_host(remaining, parser))
|
|
|
};
|
|
|
let (path, remaining) = try!(parse_path_start(
|
|
|
- remaining, UrlParserContext, scheme_type, parser));
|
|
|
- let scheme_data = RelativeSchemeData(UrlRelativeSchemeData {
|
|
|
+ remaining, Context::UrlParser, scheme_type, parser));
|
|
|
+ let scheme_data = SchemeData::Relative(RelativeSchemeData {
|
|
|
username: String::new(), password: None,
|
|
|
host: host, port: None, default_port: None, path: path
|
|
|
});
|
|
|
@@ -251,14 +241,14 @@ fn parse_relative_url<'a>(input: &'a str, scheme: String, scheme_type: SchemeTyp
|
|
|
} else {
|
|
|
// Relative path state
|
|
|
let (path, remaining) = try!(parse_path(
|
|
|
- &[], input.slice_from(1), UrlParserContext, scheme_type, parser));
|
|
|
- let scheme_data = RelativeSchemeData(if scheme_type == FileLikeRelativeScheme {
|
|
|
- UrlRelativeSchemeData {
|
|
|
+ &[], input.slice_from(1), Context::UrlParser, scheme_type, parser));
|
|
|
+ let scheme_data = SchemeData::Relative(if scheme_type == SchemeType::FileLike {
|
|
|
+ RelativeSchemeData {
|
|
|
username: String::new(), password: None, host:
|
|
|
- Domain(String::new()), port: None, default_port: None, path: path
|
|
|
+ Host::Domain(String::new()), port: None, default_port: None, path: path
|
|
|
}
|
|
|
} else {
|
|
|
- UrlRelativeSchemeData {
|
|
|
+ RelativeSchemeData {
|
|
|
username: base.username.clone(),
|
|
|
password: base.password.clone(),
|
|
|
host: base.host.clone(),
|
|
|
@@ -275,16 +265,16 @@ fn parse_relative_url<'a>(input: &'a str, scheme: String, scheme_type: SchemeTyp
|
|
|
},
|
|
|
'?' => {
|
|
|
let (query, fragment) = try!(parse_query_and_fragment(input, parser));
|
|
|
- Ok(Url { scheme: scheme, scheme_data: RelativeSchemeData(base.clone()),
|
|
|
+ Ok(Url { scheme: scheme, scheme_data: SchemeData::Relative(base.clone()),
|
|
|
query: query, fragment: fragment })
|
|
|
},
|
|
|
'#' => {
|
|
|
let fragment = Some(try!(parse_fragment(input.slice_from(1), parser)));
|
|
|
- Ok(Url { scheme: scheme, scheme_data: RelativeSchemeData(base.clone()),
|
|
|
+ Ok(Url { scheme: scheme, scheme_data: SchemeData::Relative(base.clone()),
|
|
|
query: base_query.clone(), fragment: fragment })
|
|
|
}
|
|
|
_ => {
|
|
|
- let (scheme_data, remaining) = if scheme_type == FileLikeRelativeScheme
|
|
|
+ let (scheme_data, remaining) = if scheme_type == SchemeType::FileLike
|
|
|
&& input.len() >= 2
|
|
|
&& starts_with_ascii_alpha(input)
|
|
|
&& is_match!(input.char_at(1), ':' | '|')
|
|
|
@@ -293,10 +283,10 @@ fn parse_relative_url<'a>(input: &'a str, scheme: String, scheme_type: SchemeTyp
|
|
|
{
|
|
|
// Windows drive letter quirk
|
|
|
let (path, remaining) = try!(parse_path(
|
|
|
- &[], input, UrlParserContext, scheme_type, parser));
|
|
|
- (RelativeSchemeData(UrlRelativeSchemeData {
|
|
|
+ &[], input, Context::UrlParser, scheme_type, parser));
|
|
|
+ (SchemeData::Relative(RelativeSchemeData {
|
|
|
username: String::new(), password: None,
|
|
|
- host: Domain(String::new()),
|
|
|
+ host: Host::Domain(String::new()),
|
|
|
port: None,
|
|
|
default_port: None,
|
|
|
path: path
|
|
|
@@ -305,8 +295,8 @@ fn parse_relative_url<'a>(input: &'a str, scheme: String, scheme_type: SchemeTyp
|
|
|
let base_path = base.path.slice_to(base.path.len() - 1);
|
|
|
// Relative path state
|
|
|
let (path, remaining) = try!(parse_path(
|
|
|
- base_path, input, UrlParserContext, scheme_type, parser));
|
|
|
- (RelativeSchemeData(UrlRelativeSchemeData {
|
|
|
+ base_path, input, Context::UrlParser, scheme_type, parser));
|
|
|
+ (SchemeData::Relative(RelativeSchemeData {
|
|
|
username: base.username.clone(),
|
|
|
password: base.password.clone(),
|
|
|
host: base.host.clone(),
|
|
|
@@ -326,7 +316,7 @@ fn parse_relative_url<'a>(input: &'a str, scheme: String, scheme_type: SchemeTyp
|
|
|
fn skip_slashes<'a>(input: &'a str, parser: &UrlParser) -> ParseResult<&'a str> {
|
|
|
let first_non_slash = input.find(|c| !is_match!(c, '/' | '\\')).unwrap_or(input.len());
|
|
|
if input.slice_to(first_non_slash) != "//" {
|
|
|
- try!(parser.parse_error(ExpectedTwoSlashes));
|
|
|
+ try!(parser.parse_error(ParseError::ExpectedTwoSlashes));
|
|
|
}
|
|
|
Ok(input.slice_from(first_non_slash))
|
|
|
}
|
|
|
@@ -338,7 +328,9 @@ fn parse_userinfo<'a>(input: &'a str, parser: &UrlParser)
|
|
|
for (i, c) in input.char_indices() {
|
|
|
match c {
|
|
|
'@' => {
|
|
|
- if last_at.is_some() { try!(parser.parse_error(InvalidAtSymbolInUser)) }
|
|
|
+ if last_at.is_some() {
|
|
|
+ try!(parser.parse_error(ParseError::InvalidAtSymbolInUser))
|
|
|
+ }
|
|
|
last_at = Some(i)
|
|
|
},
|
|
|
'/' | '\\' | '?' | '#' => break,
|
|
|
@@ -358,7 +350,7 @@ fn parse_userinfo<'a>(input: &'a str, parser: &UrlParser)
|
|
|
password = Some(try!(parse_password(input.slice_from(i + 1), parser)));
|
|
|
break
|
|
|
},
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
_ => {
|
|
|
try!(check_url_code_point(input, i, c, parser));
|
|
|
// The spec says to use the default encode set,
|
|
|
@@ -376,7 +368,7 @@ fn parse_password(input: &str, parser: &UrlParser) -> ParseResult<String> {
|
|
|
let mut password = String::new();
|
|
|
for (i, c, next_i) in input.char_ranges() {
|
|
|
match c {
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
_ => {
|
|
|
try!(check_url_code_point(input, i, c, parser));
|
|
|
// The spec says to use the default encode set,
|
|
|
@@ -417,7 +409,7 @@ pub fn parse_hostname<'a>(input: &'a str, parser: &UrlParser)
|
|
|
end = i;
|
|
|
break
|
|
|
},
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
c => {
|
|
|
match c {
|
|
|
'[' => inside_square_brackets = true,
|
|
|
@@ -443,7 +435,7 @@ pub fn parse_port<'a>(input: &'a str, scheme_type: SchemeType, parser: &UrlParse
|
|
|
'0'...'9' => {
|
|
|
port = port * 10 + (c as u32 - '0' as u32);
|
|
|
if port > ::std::u16::MAX as u32 {
|
|
|
- return Err(InvalidPort)
|
|
|
+ return Err(ParseError::InvalidPort)
|
|
|
}
|
|
|
has_any_digit = true;
|
|
|
},
|
|
|
@@ -451,8 +443,8 @@ pub fn parse_port<'a>(input: &'a str, scheme_type: SchemeType, parser: &UrlParse
|
|
|
end = i;
|
|
|
break
|
|
|
},
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
- _ => return Err(InvalidPort)
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
+ _ => return Err(ParseError::InvalidPort)
|
|
|
}
|
|
|
}
|
|
|
let default_port = scheme_type.default_port();
|
|
|
@@ -473,12 +465,12 @@ fn parse_file_host<'a>(input: &'a str, parser: &UrlParser) -> ParseResult<(Host,
|
|
|
end = i;
|
|
|
break
|
|
|
},
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
_ => host_input.push(c)
|
|
|
}
|
|
|
}
|
|
|
let host = if host_input.is_empty() {
|
|
|
- Domain(String::new())
|
|
|
+ Host::Domain(String::new())
|
|
|
} else {
|
|
|
try!(Host::parse(host_input.as_slice()))
|
|
|
};
|
|
|
@@ -490,13 +482,13 @@ pub fn parse_standalone_path(input: &str, parser: &UrlParser)
|
|
|
-> ParseResult<(Vec<String>, Option<String>, Option<String>)> {
|
|
|
if !input.starts_with("/") {
|
|
|
if input.starts_with("\\") {
|
|
|
- try!(parser.parse_error(InvalidBackslash));
|
|
|
+ try!(parser.parse_error(ParseError::InvalidBackslash));
|
|
|
} else {
|
|
|
- return Err(ExpectedInitialSlash)
|
|
|
+ return Err(ParseError::ExpectedInitialSlash)
|
|
|
}
|
|
|
}
|
|
|
let (path, remaining) = try!(parse_path(
|
|
|
- &[], input.slice_from(1), UrlParserContext, RelativeScheme(0), parser));
|
|
|
+ &[], input.slice_from(1), Context::UrlParser, SchemeType::Relative(0), parser));
|
|
|
let (query, fragment) = try!(parse_query_and_fragment(remaining, parser));
|
|
|
Ok((path, query, fragment))
|
|
|
}
|
|
|
@@ -511,7 +503,7 @@ pub fn parse_path_start<'a>(input: &'a str, context: Context, scheme_type: Schem
|
|
|
match input.char_at(0) {
|
|
|
'/' => i = 1,
|
|
|
'\\' => {
|
|
|
- try!(parser.parse_error(InvalidBackslash));
|
|
|
+ try!(parser.parse_error(ParseError::InvalidBackslash));
|
|
|
i = 1;
|
|
|
},
|
|
|
_ => ()
|
|
|
@@ -540,16 +532,16 @@ fn parse_path<'a>(base_path: &[String], input: &'a str, context: Context,
|
|
|
break
|
|
|
},
|
|
|
'\\' => {
|
|
|
- try!(parser.parse_error(InvalidBackslash));
|
|
|
+ try!(parser.parse_error(ParseError::InvalidBackslash));
|
|
|
ends_with_slash = true;
|
|
|
end = i;
|
|
|
break
|
|
|
},
|
|
|
- '?' | '#' if context == UrlParserContext => {
|
|
|
+ '?' | '#' if context == Context::UrlParser => {
|
|
|
end = i;
|
|
|
break
|
|
|
},
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
_ => {
|
|
|
try!(check_url_code_point(input, i, c, parser));
|
|
|
utf8_percent_encode_to(input.slice(i, next_i),
|
|
|
@@ -571,7 +563,7 @@ fn parse_path<'a>(base_path: &[String], input: &'a str, context: Context,
|
|
|
}
|
|
|
},
|
|
|
_ => {
|
|
|
- if scheme_type == FileLikeRelativeScheme
|
|
|
+ if scheme_type == SchemeType::FileLike
|
|
|
&& path.is_empty()
|
|
|
&& path_part.len() == 2
|
|
|
&& starts_with_ascii_alpha(path_part.as_slice())
|
|
|
@@ -602,7 +594,7 @@ fn parse_scheme_data<'a>(input: &'a str, parser: &UrlParser)
|
|
|
end = i;
|
|
|
break
|
|
|
},
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
_ => {
|
|
|
try!(check_url_code_point(input, i, c, parser));
|
|
|
utf8_percent_encode_to(input.slice(i, next_i),
|
|
|
@@ -623,7 +615,7 @@ fn parse_query_and_fragment(input: &str, parser: &UrlParser)
|
|
|
'#' => Ok((None, Some(try!(parse_fragment(input.slice_from(1), parser))))),
|
|
|
'?' => {
|
|
|
let (query, remaining) = try!(parse_query(
|
|
|
- input.slice_from(1), UrlParserContext, parser));
|
|
|
+ input.slice_from(1), Context::UrlParser, parser));
|
|
|
let fragment = match remaining {
|
|
|
Some(remaining) => Some(try!(parse_fragment(remaining, parser))),
|
|
|
None => None
|
|
|
@@ -642,11 +634,11 @@ pub fn parse_query<'a>(input: &'a str, context: Context, parser: &UrlParser)
|
|
|
let mut remaining = None;
|
|
|
for (i, c) in input.char_indices() {
|
|
|
match c {
|
|
|
- '#' if context == UrlParserContext => {
|
|
|
+ '#' if context == Context::UrlParser => {
|
|
|
remaining = Some(input.slice_from(i + 1));
|
|
|
break
|
|
|
},
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
_ => {
|
|
|
try!(check_url_code_point(input, i, c, parser));
|
|
|
query.push(c);
|
|
|
@@ -670,7 +662,7 @@ pub fn parse_fragment<'a>(input: &'a str, parser: &UrlParser) -> ParseResult<Str
|
|
|
let mut fragment = String::new();
|
|
|
for (i, c, next_i) in input.char_ranges() {
|
|
|
match c {
|
|
|
- '\t' | '\n' | '\r' => try!(parser.parse_error(InvalidCharacter)),
|
|
|
+ '\t' | '\n' | '\r' => try!(parser.parse_error(ParseError::InvalidCharacter)),
|
|
|
_ => {
|
|
|
try!(check_url_code_point(input, i, c, parser));
|
|
|
utf8_percent_encode_to(input.slice(i, next_i),
|
|
|
@@ -771,10 +763,10 @@ fn check_url_code_point(input: &str, i: uint, c: char, parser: &UrlParser)
|
|
|
-> ParseResult<()> {
|
|
|
if c == '%' {
|
|
|
if !starts_with_2_hex(input.slice_from(i + 1)) {
|
|
|
- try!(parser.parse_error(InvalidPercentEncoded));
|
|
|
+ try!(parser.parse_error(ParseError::InvalidPercentEncoded));
|
|
|
}
|
|
|
} else if !is_url_code_point(c) {
|
|
|
- try!(parser.parse_error(NonUrlCodePoint));
|
|
|
+ try!(parser.parse_error(ParseError::NonUrlCodePoint));
|
|
|
}
|
|
|
Ok(())
|
|
|
}
|