Skip to content

Commit

Permalink
Add parse_path(). Fix #14.
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonSapin committed Aug 27, 2014
1 parent a1fdd28 commit 03f6b33
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/lib.rs
Expand Up @@ -349,6 +349,46 @@ impl<'a> UrlParser<'a> {
pub fn parse(&self, input: &str) -> ParseResult<Url> {
parser::parse_url(input, self)
}

/// Parse `input` as a “standalone” URL path,
/// with an optional query string and fragment identifier.
///
/// This is typically found in the start line of an HTTP header.
///
/// Note that while the start line has no fragment identifier in the HTTP RFC,
/// servers typically parse it and ignore it
/// (rather than having it be part of the path or query string.)
///
/// On success, return `(path, query_string, fragment_identifier)`
#[inline]
pub fn parse_path(&self, input: &str)
-> ParseResult<(Vec<String>, Option<String>, Option<String>)> {
parser::parse_standalone_path(input, self)
}
}


/// Parse `input` as a “standalone” URL path,
/// with an optional query string and fragment identifier.
///
/// This is typically found in the start line of an HTTP header.
///
/// Note that while the start line has no fragment identifier in the HTTP RFC,
/// servers typically parse it and ignore it
/// (rather than having it be part of the path or query string.)
///
/// On success, return `(path, query_string, fragment_identifier)`
///
/// ```rust
/// let (path, query, fragment) = url::parse_path("/foo/bar/../baz?q=42").unwrap();
/// assert_eq!(path, vec!["foo".to_string(), "baz".to_string()]);
/// assert_eq!(query, Some("q=42".to_string()));
/// assert_eq!(fragment, None);
/// ```
#[inline]
pub fn parse_path(input: &str)
-> ParseResult<(Vec<String>, Option<String>, Option<String>)> {
UrlParser::new().parse_path(input)
}


Expand Down
18 changes: 18 additions & 0 deletions src/parser.rs
Expand Up @@ -45,6 +45,7 @@ pub enum ParseError {
InvalidPercentEncoded,
InvalidAtSymbolInUser,
ExpectedTwoSlashes,
ExpectedInitialSlash,
NonUrlCodePoint,
RelativeUrlWithScheme,
RelativeUrlWithoutBase,
Expand All @@ -68,6 +69,7 @@ impl Show for ParseError {
InvalidPercentEncoded => "Invalid percent-encoded sequence",
InvalidAtSymbolInUser => "Invalid @-symbol in user",
ExpectedTwoSlashes => "Expected two slashes (//)",
ExpectedInitialSlash => "Expected the input to start with a slash",
NonUrlCodePoint => "Non URL code point",
RelativeUrlWithScheme => "Relative URL with scheme",
RelativeUrlWithoutBase => "Relative URL without a base",
Expand Down Expand Up @@ -472,6 +474,22 @@ fn parse_file_host<'a>(input: &'a str, parser: &UrlParser) -> ParseResult<(Host,
}


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));
} else {
return Err(ExpectedInitialSlash)
}
}
let (path, remaining) = try!(parse_path(
[], input.slice_from(1), UrlParserContext, RelativeScheme(0), parser));
let (query, fragment) = try!(parse_query_and_fragment(remaining, parser));
Ok((path, query, fragment))
}


pub fn parse_path_start<'a>(input: &'a str, context: Context, scheme_type: SchemeType,
parser: &UrlParser)
-> ParseResult<(Vec<String>, &'a str)> {
Expand Down

0 comments on commit 03f6b33

Please sign in to comment.