Ver Fonte

Add some early returns to reduce indentation.

Simon Sapin há 12 anos atrás
pai
commit
de6bd47a1f
1 ficheiros alterados com 167 adições e 167 exclusões
  1. 167 167
      src/parser.rs

+ 167 - 167
src/parser.rs

@@ -31,49 +31,48 @@ macro_rules! is_match(
 pub fn parse_url(input: &str, base_url: Option<&Url>, parse_error: ErrorHandler)
                  -> ParseResult<Url> {
     let input = input.trim_chars(&[' ', '\t', '\n', '\r', '\x0C']);
-    match parse_scheme(input, /* in_setter = */ false) {
-        Some((scheme, remaining)) => {
-            if scheme.as_slice() == "file" {
-                // Relative state?
-                match base_url {
-                    Some(base) if scheme == base.scheme => {
-                        try!(parse_error("Relative URL with a scheme"));
-                        parse_relative_url(scheme, remaining, base, parse_error)
-                    },
-                    _ => parse_relative_url(scheme, remaining, &Url {
-                        scheme: String::new(), query: None, fragment: None,
-                        scheme_data: RelativeSchemeData(SchemeRelativeUrl {
-                            username: String::new(), password: None, host: Domain(String::new()),
-                            port: String::new(), path: Vec::new()
-                        })
-                    }, parse_error),
-                }
-            } else if is_relative_scheme(scheme.as_slice()) {
-                match base_url {
-                    Some(base) if scheme == base.scheme => {
-                        // Relative or authority state
-                        if remaining.starts_with("//") {
-                            parse_absolute_url(scheme, remaining, parse_error)
-                        } else {
-                            try!(parse_error("Relative URL with a scheme"));
-                            parse_relative_url(scheme, remaining, base, parse_error)
-                        }
-                    },
-                    _ => parse_absolute_url(scheme, remaining, parse_error),
-                }
-            } else {
-                // Scheme data state
-                let (scheme_data, remaining) = try!(parse_scheme_data(remaining, parse_error));
-                let (query, fragment) = try!(parse_query_and_fragment(remaining, parse_error));
-                Ok(Url { scheme: scheme, scheme_data: OtherSchemeData(scheme_data),
-                         query: query, fragment: fragment })
-            }
-        },
+    let (scheme, remaining) = match parse_scheme(input, /* in_setter = */ false) {
         // No-scheme state
         None => match base_url {
-            None => Err("Relative URL without a base"),
-            Some(base) => parse_relative_url(base.scheme.clone(), input, base, parse_error)
+            None => return Err("Relative URL without a base"),
+            Some(base) => return parse_relative_url(base.scheme.clone(), input, base, parse_error)
+        },
+        Some((scheme, remaining)) => (scheme, remaining)
+    };
+    if scheme.as_slice() == "file" {
+        // Relative state?
+        match base_url {
+            Some(base) if scheme == base.scheme => {
+                try!(parse_error("Relative URL with a scheme"));
+                parse_relative_url(scheme, remaining, base, parse_error)
+            },
+            _ => parse_relative_url(scheme, remaining, &Url {
+                scheme: String::new(), query: None, fragment: None,
+                scheme_data: RelativeSchemeData(SchemeRelativeUrl {
+                    username: String::new(), password: None, host: Domain(String::new()),
+                    port: String::new(), path: Vec::new()
+                })
+            }, parse_error),
+        }
+    } else if is_relative_scheme(scheme.as_slice()) {
+        match base_url {
+            Some(base) if scheme == base.scheme => {
+                // Relative or authority state
+                if remaining.starts_with("//") {
+                    parse_absolute_url(scheme, remaining, parse_error)
+                } else {
+                    try!(parse_error("Relative URL with a scheme"));
+                    parse_relative_url(scheme, remaining, base, parse_error)
+                }
+            },
+            _ => parse_absolute_url(scheme, remaining, parse_error),
         }
+    } else {
+        // Scheme data state
+        let (scheme_data, remaining) = try!(parse_scheme_data(remaining, parse_error));
+        let (query, fragment) = try!(parse_query_and_fragment(remaining, parse_error));
+        Ok(Url { scheme: scheme, scheme_data: OtherSchemeData(scheme_data),
+                 query: query, fragment: fragment })
     }
 }
 
@@ -123,124 +122,125 @@ fn parse_absolute_url<'a>(scheme: String, input: &'a str, parse_error: ErrorHand
 
 fn parse_relative_url<'a>(scheme: String, input: &'a str, base: &Url, parse_error: ErrorHandler)
                           -> ParseResult<Url> {
-    match base.scheme_data {
-        OtherSchemeData(_) => Err("Relative URL with a non-relative-scheme base"),
-        RelativeSchemeData(ref base_scheme_data) => if input.is_empty() {
-            Ok(Url { scheme: scheme, scheme_data: base.scheme_data.clone(),
-                     query: base.query.clone(), fragment: None })
-        } else {
-            let in_file_scheme = scheme.as_slice() == "file";
-            match input.char_at(0) {
-                '/' | '\\' => {
-                    // Relative slash state
-                    if input.len() > 1 && is_match!(input.char_at(1), '/' | '\\') {
-                        if in_file_scheme {
-                            let remaining = input.slice_from(2);
-                            let (host, remaining) = if remaining.len() >= 2
-                               && starts_with_ascii_alpha(remaining)
-                               && is_match!(remaining.char_at(1), ':' | '|')
-                               && (remaining.len() == 2
-                                   || is_match!(remaining.char_at(2),
-                                                 '/' | '\\' | '?' | '#'))
-                            {
-                                // Windows drive letter quirk
-                                (Domain(String::new()), remaining)
-                            } else {
-                                // File host state
-                                try!(parse_file_host(remaining, parse_error))
-                            };
-                            let (path, remaining) = try!(parse_path_start(
-                                remaining, /* full_url= */ true,
-                                in_file_scheme, parse_error));
-                            let scheme_data = RelativeSchemeData(SchemeRelativeUrl {
-                                username: String::new(), password: None,
-                                host: host, port: String::new(), path: path
-                            });
-                            let (query, fragment) = try!(parse_query_and_fragment(
-                                remaining, parse_error));
-                            Ok(Url { scheme: scheme, scheme_data: scheme_data,
-                                     query: query, fragment: fragment })
-                        } else {
-                            parse_absolute_url(scheme, input, parse_error)
-                        }
-                    } 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 {
-                            SchemeRelativeUrl {
-                                username: String::new(), password: None, host:
-                                Domain(String::new()), port: String::new(), path: path
-                            }
-                        } else {
-                            SchemeRelativeUrl {
-                                username: base_scheme_data.username.clone(),
-                                password: base_scheme_data.password.clone(),
-                                host: base_scheme_data.host.clone(),
-                                port: base_scheme_data.port.clone(),
-                                path: path
-                            }
-                        });
-                        let (query, fragment) = try!(
-                            parse_query_and_fragment(remaining, parse_error));
-                        Ok(Url { scheme: scheme, scheme_data: scheme_data,
-                                 query: query, fragment: fragment })
-                    }
-                },
-                '?' => {
-                    let (query, fragment) = try!(parse_query_and_fragment(input, parse_error));
-                    Ok(Url { scheme: scheme, scheme_data: base.scheme_data.clone(),
-                             query: query, fragment: fragment })
-                },
-                '#' => {
-                    Ok(Url { scheme: scheme, scheme_data: base.scheme_data.clone(),
-                             query: base.query.clone(),
-                             fragment: Some(try!(
-                                parse_fragment(input.slice_from(1), parse_error))) })
-                }
-                _ => {
-                    let (scheme_data, remaining) = if in_file_scheme
-                       && input.len() >= 2
-                       && starts_with_ascii_alpha(input)
-                       && is_match!(input.char_at(1), ':' | '|')
-                       && (input.len() == 2
-                           || is_match!(input.char_at(2), '/' | '\\' | '?' | '#'))
+    let base_scheme_data = match base.scheme_data {
+        OtherSchemeData(_) => return Err("Relative URL with a non-relative-scheme base"),
+        RelativeSchemeData(ref base_scheme_data) => {
+            if input.is_empty() {
+                return Ok(Url { scheme: scheme, scheme_data: base.scheme_data.clone(),
+                                query: base.query.clone(), fragment: None })
+            }
+            base_scheme_data
+        }
+    };
+    let in_file_scheme = scheme.as_slice() == "file";
+    match input.char_at(0) {
+        '/' | '\\' => {
+            // Relative slash state
+            if input.len() > 1 && is_match!(input.char_at(1), '/' | '\\') {
+                if in_file_scheme {
+                    let remaining = input.slice_from(2);
+                    let (host, remaining) = if remaining.len() >= 2
+                       && starts_with_ascii_alpha(remaining)
+                       && is_match!(remaining.char_at(1), ':' | '|')
+                       && (remaining.len() == 2
+                           || is_match!(remaining.char_at(2),
+                                         '/' | '\\' | '?' | '#'))
                     {
                         // Windows drive letter quirk
-                        let (path, remaining) = try!(parse_path(
-                            Vec::new(), input, /* full_url= */ true,
-                            in_file_scheme, parse_error));
-                         (RelativeSchemeData(SchemeRelativeUrl {
-                            username: String::new(), password: None,
-                            host: Domain(String::new()),
-                            port: String::new(),
-                            path: path
-                        }), remaining)
+                        (Domain(String::new()), remaining)
                     } else {
-                        let base_path = base_scheme_data.path.as_slice();
-                        let initial_path = Vec::from_slice(
-                            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));
-                        (RelativeSchemeData(SchemeRelativeUrl {
-                            username: base_scheme_data.username.clone(),
-                            password: base_scheme_data.password.clone(),
-                            host: base_scheme_data.host.clone(),
-                            port: base_scheme_data.port.clone(),
-                            path: path
-                        }), remaining)
+                        // File host state
+                        try!(parse_file_host(remaining, parse_error))
                     };
-                    let (query, fragment) = try!(parse_query_and_fragment(remaining, parse_error));
+                    let (path, remaining) = try!(parse_path_start(
+                        remaining, /* full_url= */ true,
+                        in_file_scheme, parse_error));
+                    let scheme_data = RelativeSchemeData(SchemeRelativeUrl {
+                        username: String::new(), password: None,
+                        host: host, port: String::new(), path: path
+                    });
+                    let (query, fragment) = try!(parse_query_and_fragment(
+                        remaining, parse_error));
                     Ok(Url { scheme: scheme, scheme_data: scheme_data,
                              query: query, fragment: fragment })
+                } else {
+                    parse_absolute_url(scheme, input, parse_error)
                 }
+            } 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 {
+                    SchemeRelativeUrl {
+                        username: String::new(), password: None, host:
+                        Domain(String::new()), port: String::new(), path: path
+                    }
+                } else {
+                    SchemeRelativeUrl {
+                        username: base_scheme_data.username.clone(),
+                        password: base_scheme_data.password.clone(),
+                        host: base_scheme_data.host.clone(),
+                        port: base_scheme_data.port.clone(),
+                        path: path
+                    }
+                });
+                let (query, fragment) = try!(
+                    parse_query_and_fragment(remaining, parse_error));
+                Ok(Url { scheme: scheme, scheme_data: scheme_data,
+                         query: query, fragment: fragment })
             }
+        },
+        '?' => {
+            let (query, fragment) = try!(parse_query_and_fragment(input, parse_error));
+            Ok(Url { scheme: scheme, scheme_data: base.scheme_data.clone(),
+                     query: query, fragment: fragment })
+        },
+        '#' => {
+            Ok(Url { scheme: scheme, scheme_data: base.scheme_data.clone(),
+                     query: base.query.clone(),
+                     fragment: Some(try!(
+                        parse_fragment(input.slice_from(1), parse_error))) })
+        }
+        _ => {
+            let (scheme_data, remaining) = if in_file_scheme
+               && input.len() >= 2
+               && starts_with_ascii_alpha(input)
+               && is_match!(input.char_at(1), ':' | '|')
+               && (input.len() == 2
+                   || is_match!(input.char_at(2), '/' | '\\' | '?' | '#'))
+            {
+                // Windows drive letter quirk
+                let (path, remaining) = try!(parse_path(
+                    Vec::new(), input, /* full_url= */ true,
+                    in_file_scheme, parse_error));
+                 (RelativeSchemeData(SchemeRelativeUrl {
+                    username: String::new(), password: None,
+                    host: Domain(String::new()),
+                    port: String::new(),
+                    path: path
+                }), remaining)
+            } else {
+                let base_path = base_scheme_data.path.as_slice();
+                let initial_path = Vec::from_slice(
+                    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));
+                (RelativeSchemeData(SchemeRelativeUrl {
+                    username: base_scheme_data.username.clone(),
+                    password: base_scheme_data.password.clone(),
+                    host: base_scheme_data.host.clone(),
+                    port: base_scheme_data.port.clone(),
+                    path: path
+                }), remaining)
+            };
+            let (query, fragment) = try!(parse_query_and_fragment(remaining, parse_error));
+            Ok(Url { scheme: scheme, scheme_data: scheme_data,
+                     query: query, fragment: fragment })
         }
     }
-
 }
 
 
@@ -514,25 +514,25 @@ fn parse_scheme_data<'a>(input: &'a str, parse_error: ErrorHandler)
 
 fn parse_query_and_fragment(input: &str, parse_error: ErrorHandler)
                             -> ParseResult<(Option<String>, Option<String>)> {
-    Ok(if input.is_empty() {
-        (None, None)
-    } else {
-        match input.char_at(0) {
-            '#' => (None, Some(try!(parse_fragment(input.slice_from(1), parse_error)))),
-            '?' => {
-                let (query, remaining) = try!(parse_query(
-                    input.slice_from(1),
-                    UTF_8 as EncodingRef,  // TODO
-                    /* full_url = */ true,
-                    parse_error));
-                (Some(query), match remaining {
-                    Some(remaining) => Some(try!(parse_fragment(remaining, parse_error))),
-                    None => None
-                })
-            },
-            _ => fail!("Programming error")
-        }
-    })
+    if input.is_empty() {
+        return Ok((None, None))
+    }
+    match input.char_at(0) {
+        '#' => Ok((None, Some(try!(parse_fragment(input.slice_from(1), parse_error))))),
+        '?' => {
+            let (query, remaining) = try!(parse_query(
+                input.slice_from(1),
+                UTF_8 as EncodingRef,  // TODO
+                /* full_url = */ true,
+                parse_error));
+            let fragment = match remaining {
+                Some(remaining) => Some(try!(parse_fragment(remaining, parse_error))),
+                None => None
+            };
+            Ok((Some(query), fragment))
+        },
+        _ => fail!("Programming error")
+    }
 }