Explorar el Código

Avoid boolean arguments.

Simon Sapin hace 12 años
padre
commit
09788a561c
Se han modificado 2 ficheros con 67 adiciones y 52 borrados
  1. 57 44
      src/parser.rs
  2. 10 8
      src/url.rs

+ 57 - 44
src/parser.rs

@@ -27,11 +27,23 @@ macro_rules! is_match(
     );
 )
 
+#[deriving(PartialEq, Eq)]
+pub enum Context {
+    UrlParserContext,
+    SetterContext,
+}
+
+#[deriving(PartialEq, Eq)]
+pub enum SchemeType {
+    FileScheme,
+    NonFileScheme,
+}
+
 
 pub fn parse_url(input: &str, base_url: Option<&Url>, parse_error: ErrorHandler)
                  -> ParseResult<Url> {
     let input = input.trim_chars(&[' ', '\t', '\n', '\r', '\x0C']);
-    let (scheme, remaining) = match parse_scheme(input, /* in_setter = */ false) {
+    let (scheme, remaining) = match parse_scheme(input, UrlParserContext) {
         // No-scheme state
         None => match base_url {
             None => return Err("Relative URL without a base"),
@@ -77,7 +89,7 @@ pub fn parse_url(input: &str, base_url: Option<&Url>, parse_error: ErrorHandler)
 }
 
 
-pub fn parse_scheme<'a>(input: &'a str, in_setter: bool) -> Option<(String, &'a str)> {
+pub fn parse_scheme<'a>(input: &'a str, context: Context) -> Option<(String, &'a str)> {
     if input.is_empty() || !starts_with_ascii_alpha(input) {
         return None
     }
@@ -91,10 +103,10 @@ pub fn parse_scheme<'a>(input: &'a str, in_setter: bool) -> Option<(String, &'a
             _ => return None,
         }
     }
-    if in_setter {
-        Some((input.to_ascii_lower(), ""))
-    } else {
-        None
+    // EOF
+    match context {
+        SetterContext => Some((input.to_ascii_lower(), "")),
+        UrlParserContext => None
     }
 }
 
@@ -106,13 +118,9 @@ fn parse_absolute_url<'a>(scheme: String, input: &'a str, parse_error: ErrorHand
     // Authority state
     let (username, password, remaining) = try!(parse_userinfo(remaining, parse_error));
     // Host state
-    let (host, port, remaining) = try!(
-        parse_hostname(remaining, scheme.as_slice(), parse_error, /* skip_port = */ false));
+    let (host, port, remaining) = try!(parse_host(remaining, scheme.as_slice(), parse_error));
     let (path, remaining) = try!(parse_path_start(
-        remaining,
-        /* full_url= */ true,
-        /* in_file_scheme= */ false,
-        parse_error));
+        remaining, UrlParserContext, NonFileScheme, parse_error));
     let scheme_data = RelativeSchemeData(SchemeRelativeUrl {
         username: username, password: password, host: host, port: port, path: path });
     let (query, fragment) = try!(parse_query_and_fragment(remaining, parse_error));
@@ -132,12 +140,12 @@ fn parse_relative_url<'a>(scheme: String, input: &'a str, base: &Url, parse_erro
             base_scheme_data
         }
     };
-    let in_file_scheme = scheme.as_slice() == "file";
+    let scheme_type = if scheme.as_slice() == "file" { FileScheme } else { NonFileScheme };
     match input.char_at(0) {
         '/' | '\\' => {
             // Relative slash state
             if input.len() > 1 && is_match!(input.char_at(1), '/' | '\\') {
-                if in_file_scheme {
+                if scheme_type == FileScheme {
                     let remaining = input.slice_from(2);
                     let (host, remaining) = if remaining.len() >= 2
                        && starts_with_ascii_alpha(remaining)
@@ -153,8 +161,8 @@ fn parse_relative_url<'a>(scheme: String, input: &'a str, base: &Url, parse_erro
                         try!(parse_file_host(remaining, parse_error))
                     };
                     let (path, remaining) = try!(parse_path_start(
-                        remaining, /* full_url= */ true,
-                        in_file_scheme, parse_error));
+                        remaining, UrlParserContext,
+                        scheme_type, parse_error));
                     let scheme_data = RelativeSchemeData(SchemeRelativeUrl {
                         username: String::new(), password: None,
                         host: host, port: String::new(), path: path
@@ -169,9 +177,9 @@ fn parse_relative_url<'a>(scheme: String, input: &'a str, base: &Url, parse_erro
             } else {
                 // Relative path state
                 let (path, remaining) = try!(parse_path(
-                    Vec::new(), input.slice_from(1), /* full_url= */ true,
-                    in_file_scheme, parse_error));
-                let scheme_data = RelativeSchemeData(if in_file_scheme {
+                    Vec::new(), input.slice_from(1), UrlParserContext,
+                    scheme_type, parse_error));
+                let scheme_data = RelativeSchemeData(if scheme_type == FileScheme {
                     SchemeRelativeUrl {
                         username: String::new(), password: None, host:
                         Domain(String::new()), port: String::new(), path: path
@@ -203,7 +211,7 @@ fn parse_relative_url<'a>(scheme: String, input: &'a str, base: &Url, parse_erro
                         parse_fragment(input.slice_from(1), parse_error))) })
         }
         _ => {
-            let (scheme_data, remaining) = if in_file_scheme
+            let (scheme_data, remaining) = if scheme_type == FileScheme
                && input.len() >= 2
                && starts_with_ascii_alpha(input)
                && is_match!(input.char_at(1), ':' | '|')
@@ -212,8 +220,8 @@ fn parse_relative_url<'a>(scheme: String, input: &'a str, base: &Url, parse_erro
             {
                 // Windows drive letter quirk
                 let (path, remaining) = try!(parse_path(
-                    Vec::new(), input, /* full_url= */ true,
-                    in_file_scheme, parse_error));
+                    Vec::new(), input, UrlParserContext,
+                    scheme_type, parse_error));
                  (RelativeSchemeData(SchemeRelativeUrl {
                     username: String::new(), password: None,
                     host: Domain(String::new()),
@@ -226,8 +234,8 @@ fn parse_relative_url<'a>(scheme: String, input: &'a str, base: &Url, parse_erro
                     base_path.slice_to(base_path.len() - 1));
                 // Relative path state
                 let (path, remaining) = try!(parse_path(
-                    initial_path, input, /* full_url= */ true,
-                    in_file_scheme, parse_error));
+                    initial_path, input, UrlParserContext,
+                    scheme_type, parse_error));
                 (RelativeSchemeData(SchemeRelativeUrl {
                     username: base_scheme_data.username.clone(),
                     password: base_scheme_data.password.clone(),
@@ -308,23 +316,28 @@ fn parse_password(input: &str, parse_error: ErrorHandler) -> ParseResult<String>
 }
 
 
-pub fn parse_hostname<'a>(input: &'a str, scheme: &str, parse_error: ErrorHandler,
-                          skip_port: bool)
+pub fn parse_host<'a>(input: &'a str, scheme: &str, parse_error: ErrorHandler)
                           -> ParseResult<(Host, String, &'a str)> {
+    let (host, remaining) = try!(parse_hostname(input, parse_error));
+    let (port, remaining) = if remaining.starts_with(":") {
+        try!(parse_port(remaining.slice_from(1), scheme, parse_error))
+    } else {
+        (String::new(), remaining)
+    };
+    Ok((host, port, remaining))
+}
+
+
+pub fn parse_hostname<'a>(input: &'a str, parse_error: ErrorHandler)
+                      -> ParseResult<(Host, &'a str)> {
     let mut inside_square_brackets = false;
     let mut host_input = String::new();
     let mut end = input.len();
     for (i, c) in input.char_indices() {
         match c {
             ':' if !inside_square_brackets => {
-                let host = try!(Host::parse(host_input.as_slice()));
-                return Ok(if skip_port {
-                    (host, String::new(), "")
-                } else {
-                    let (port, remaining) = try!(
-                        parse_port(input.slice_from(i + 1), scheme, parse_error));
-                    (host, port, remaining)
-                })
+                end = i;
+                break
             },
             '/' | '\\' | '?' | '#' => {
                 end = i;
@@ -342,7 +355,7 @@ pub fn parse_hostname<'a>(input: &'a str, scheme: &str, parse_error: ErrorHandle
         }
     }
     let host = try!(Host::parse(host_input.as_slice()));
-    Ok((host, String::new(), input.slice_from(end)))
+    Ok((host, input.slice_from(end)))
 }
 
 
@@ -404,7 +417,7 @@ fn parse_file_host<'a>(input: &'a str, parse_error: ErrorHandler) -> ParseResult
 }
 
 
-pub fn parse_path_start<'a>(input: &'a str, full_url: bool, in_file_scheme: bool,
+pub fn parse_path_start<'a>(input: &'a str, context: Context, scheme_type: SchemeType,
                             parse_error: ErrorHandler)
                             -> ParseResult<(Vec<String>, &'a str)> {
     let mut i = 0;
@@ -419,12 +432,12 @@ pub fn parse_path_start<'a>(input: &'a str, full_url: bool, in_file_scheme: bool
             _ => ()
         }
     }
-    parse_path(Vec::new(), input.slice_from(i), full_url, in_file_scheme, parse_error)
+    parse_path(Vec::new(), input.slice_from(i), context, scheme_type, parse_error)
 }
 
 
-fn parse_path<'a>(base_path: Vec<String>, input: &'a str, full_url: bool, in_file_scheme: bool,
-                  parse_error: ErrorHandler)
+fn parse_path<'a>(base_path: Vec<String>, input: &'a str, context: Context,
+                  scheme_type: SchemeType, parse_error: ErrorHandler)
                   -> ParseResult<(Vec<String>, &'a str)> {
     // Relative path state
     let mut path = base_path;
@@ -447,7 +460,7 @@ fn parse_path<'a>(base_path: Vec<String>, input: &'a str, full_url: bool, in_fil
                     end = i;
                     break
                 },
-                '?' | '#' if full_url => {
+                '?' | '#' if context == UrlParserContext => {
                     end = i;
                     break
                 },
@@ -473,7 +486,7 @@ fn parse_path<'a>(base_path: Vec<String>, input: &'a str, full_url: bool, in_fil
                 }
             },
             _ => {
-                if in_file_scheme
+                if scheme_type == FileScheme
                    && path.is_empty()
                    && path_part.len() == 2
                    && starts_with_ascii_alpha(path_part.as_slice())
@@ -527,7 +540,7 @@ fn parse_query_and_fragment(input: &str, parse_error: ErrorHandler)
             let (query, remaining) = try!(parse_query(
                 input.slice_from(1),
                 UTF_8 as EncodingRef,  // TODO
-                /* full_url = */ true,
+                UrlParserContext,
                 parse_error));
             let fragment = match remaining {
                 Some(remaining) => Some(try!(parse_fragment(remaining, parse_error))),
@@ -540,14 +553,14 @@ fn parse_query_and_fragment(input: &str, parse_error: ErrorHandler)
 }
 
 
-pub fn parse_query<'a>(input: &'a str, encoding_override: EncodingRef, full_url: bool,
+pub fn parse_query<'a>(input: &'a str, encoding_override: EncodingRef, context: Context,
                    parse_error: ErrorHandler)
                    -> ParseResult<(String, Option<&'a str>)> {
     let mut query = String::new();
     let mut remaining = None;
     for (i, c) in input.char_indices() {
         match c {
-            '#' if full_url => {
+            '#' if context == UrlParserContext => {
                 remaining = Some(input.slice_from(i + 1));
                 break
             },

+ 10 - 8
src/url.rs

@@ -107,7 +107,7 @@ impl Url {
 
     /// `URLUtils.protocol` setter
     pub fn set_scheme(&mut self, input: &str) -> ParseResult<()> {
-        match parser::parse_scheme(input.as_slice(), /* in_setter = */ true) {
+        match parser::parse_scheme(input.as_slice(), parser::SetterContext) {
             Some((scheme, _)) => {
                 self.scheme = scheme;
                 Ok(())
@@ -145,8 +145,8 @@ impl Url {
     pub fn set_host_and_port(&mut self, input: &str) -> ParseResult<()> {
         match self.scheme_data {
             RelativeSchemeData(SchemeRelativeUrl { ref mut host, ref mut port, .. }) => {
-                let (new_host, new_port, _) = try!(parser::parse_hostname(
-                    input, self.scheme.as_slice(), silent_handler, /* skip_port = */ false));
+                let (new_host, new_port, _) = try!(parser::parse_host(
+                    input, self.scheme.as_slice(), silent_handler));
                 *host = new_host;
                 *port = new_port;
                 Ok(())
@@ -159,8 +159,8 @@ impl Url {
     pub fn set_host(&mut self, input: &str) -> ParseResult<()> {
         match self.scheme_data {
             RelativeSchemeData(SchemeRelativeUrl { ref mut host, .. }) => {
-                let (new_host, _, _) = try!(parser::parse_hostname(
-                    input, self.scheme.as_slice(), silent_handler, /* skip_port = */ true));
+                let (new_host, _) = try!(parser::parse_hostname(
+                    input, silent_handler));
                 *host = new_host;
                 Ok(())
             },
@@ -189,8 +189,10 @@ impl Url {
         match self.scheme_data {
             RelativeSchemeData(SchemeRelativeUrl { ref mut path, .. }) => {
                 let (new_path, _) = try!(parser::parse_path_start(
-                    input, /* full_url = */ false,
-                    self.scheme.as_slice() == "file", silent_handler));
+                    input, parser::SetterContext,
+                    if self.scheme.as_slice() == "file" { parser::FileScheme }
+                        else { parser::NonFileScheme },
+                    silent_handler));
                 *path = new_path;
                 Ok(())
             },
@@ -211,7 +213,7 @@ impl Url {
             let input = if input.starts_with("?") { input.slice_from(1) } else { input };
             let encoding_override = UTF_8 as EncodingRef;  // TODO
             let (new_query, _) = try!(parser::parse_query(
-                input, encoding_override, /* full_url = */ false, silent_handler));
+                input, encoding_override, parser::SetterContext, silent_handler));
             Some(new_query)
         };
         Ok(())