Просмотр исходного кода

Make context a field of Parser.

Simon Sapin 10 лет назад
Родитель
Сommit
194da72e7d
2 измененных файлов с 27 добавлено и 28 удалено
  1. 1 0
      src/lib.rs
  2. 26 28
      src/parser.rs

+ 1 - 0
src/lib.rs

@@ -199,6 +199,7 @@ impl Url {
             base_url: base_url,
             query_encoding_override: encoding_override,
             log_syntax_violation: log_syntax_violation,
+            context: parser::Context::UrlParser,
         }.parse_url(input)
     }
 

+ 26 - 28
src/parser.rs

@@ -63,12 +63,6 @@ impl From<::idna::uts46::Errors> for ParseError {
     fn from(_: ::idna::uts46::Errors) -> ParseError { ParseError::IdnaError }
 }
 
-#[derive(PartialEq, Eq)]
-pub enum Context {
-    UrlParser,
-    Setter,
-}
-
 #[derive(Copy, Clone)]
 pub enum SchemeType {
     File,
@@ -109,6 +103,13 @@ pub struct Parser<'a> {
     pub base_url: Option<&'a Url>,
     pub query_encoding_override: EncodingOverride,
     pub log_syntax_violation: Option<&'a Fn(&'static str)>,
+    pub context: Context,
+}
+
+#[derive(PartialEq, Eq)]
+pub enum Context {
+    UrlParser,
+    Setter,
 }
 
 impl<'a> Parser<'a> {
@@ -133,7 +134,7 @@ impl<'a> Parser<'a> {
         if input.len() < original_input.len() {
             self.syntax_violation("leading or trailing control or space character")
         }
-        if let Ok(remaining) = self.parse_scheme(input, Context::UrlParser) {
+        if let Ok(remaining) = self.parse_scheme(input) {
             return self.parse_with_scheme(remaining)
         }
 
@@ -156,7 +157,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    pub fn parse_scheme<'i>(&mut self, input: &'i str, context: Context) -> Result<&'i str, ()> {
+    pub fn parse_scheme<'i>(&mut self, input: &'i str) -> Result<&'i str, ()> {
         if input.is_empty() || !input.starts_with(ascii_alpha) {
             return Err(())
         }
@@ -174,7 +175,7 @@ impl<'a> Parser<'a> {
             }
         }
         // EOF before ':'
-        match context {
+        match self.context {
             Context::Setter => Ok(""),
             Context::UrlParser => {
                 self.serialization.clear();
@@ -234,7 +235,7 @@ impl<'a> Parser<'a> {
         let remaining = if relative {
             let path_start = self.serialization.len();
             self.serialization.push('/');
-            self.parse_path(scheme_type, &mut false, path_start, &input[1..], Context::UrlParser)
+            self.parse_path(scheme_type, &mut false, path_start, &input[1..])
         } else {
             self.parse_non_relative_path(input)
         };
@@ -356,13 +357,11 @@ impl<'a> Parser<'a> {
                     let host_end = try!(to_u32(self.serialization.len()));
                     let mut has_host = !matches!(host, HostInternal::None);
                     let remaining = if path_start {
-                        self.parse_path_start(
-                            SchemeType::File, &mut has_host, remaining, Context::UrlParser)
+                        self.parse_path_start(SchemeType::File, &mut has_host, remaining)
                     } else {
                         let path_start = self.serialization.len();
                         self.serialization.push('/');
-                        self.parse_path(SchemeType::File, &mut has_host, path_start,
-                                        remaining, Context::UrlParser)
+                        self.parse_path(SchemeType::File, &mut has_host, path_start, remaining)
                     };
                     // FIXME: deal with has_host
                     let (query_start, fragment_start) =
@@ -393,7 +392,7 @@ impl<'a> Parser<'a> {
                         }
                     }
                     let remaining = self.parse_path(
-                        SchemeType::File, &mut false, path_start, input, Context::UrlParser);
+                        SchemeType::File, &mut false, path_start, input);
                     let (query_start, fragment_start) =
                         try!(self.parse_query_and_fragment(scheme_end, remaining));
                     let path_start = path_start as u32;
@@ -425,8 +424,7 @@ impl<'a> Parser<'a> {
                     self.serialization.push_str(before_query);
                     self.pop_path(SchemeType::File, base_url.path_start as usize);
                     let remaining = self.parse_path(
-                        SchemeType::File, &mut true, base_url.path_start as usize,
-                        input, Context::UrlParser);
+                        SchemeType::File, &mut true, base_url.path_start as usize, input);
                     let non_relative = false;
                     self.with_query_and_fragment(
                         non_relative, base_url.scheme_end, base_url.username_end, base_url.host_start,
@@ -436,7 +434,7 @@ impl<'a> Parser<'a> {
                     let scheme_end = "file".len() as u32;
                     let path_start = "file://".len();
                     let remaining = self.parse_path(
-                        SchemeType::File, &mut false, path_start, input, Context::UrlParser);
+                        SchemeType::File, &mut false, path_start, input);
                     let (query_start, fragment_start) =
                         try!(self.parse_query_and_fragment(scheme_end, remaining));
                     let path_start = path_start as u32;
@@ -507,7 +505,7 @@ impl<'a> Parser<'a> {
                 debug_assert!(base_url.byte_at(path_start) == b'/');
                 self.serialization.push_str(base_url.slice(..path_start + 1));
                 let remaining = self.parse_path(
-                    scheme_type, &mut true, path_start as usize, &input[1..], Context::UrlParser);
+                    scheme_type, &mut true, path_start as usize, &input[1..]);
                 let non_relative = false;
                 self.with_query_and_fragment(
                     non_relative, base_url.scheme_end, base_url.username_end, base_url.host_start,
@@ -523,7 +521,7 @@ impl<'a> Parser<'a> {
                 // FIXME spec says just "remove last entry", not the "pop" algorithm
                 self.pop_path(scheme_type, base_url.path_start as usize);
                 let remaining = self.parse_path(
-                    scheme_type, &mut true, base_url.path_start as usize, input, Context::UrlParser);
+                    scheme_type, &mut true, base_url.path_start as usize, input);
                 let non_relative = false;
                 self.with_query_and_fragment(
                     non_relative, base_url.scheme_end, base_url.username_end, base_url.host_start,
@@ -546,7 +544,7 @@ impl<'a> Parser<'a> {
         // path state
         let path_start = try!(to_u32(self.serialization.len()));
         let remaining = self.parse_path_start(
-            scheme_type, &mut true, remaining, Context::UrlParser);
+            scheme_type, &mut true, remaining);
         self.with_query_and_fragment(non_relative, scheme_end, username_end, host_start,
                                      host_end, host, port, path_start, remaining)
     }
@@ -732,7 +730,7 @@ impl<'a> Parser<'a> {
     }
 
     fn parse_path_start<'i>(&mut self, scheme_type: SchemeType, has_host: &mut bool,
-                            mut input: &'i str, context: Context)
+                            mut input: &'i str)
                             -> &'i str {
         // Path start state
         let mut iter = input.chars();
@@ -746,11 +744,11 @@ impl<'a> Parser<'a> {
         }
         let path_start = self.serialization.len();
         self.serialization.push('/');
-        self.parse_path(scheme_type, has_host, path_start, input, context)
+        self.parse_path(scheme_type, has_host, path_start, input)
     }
 
     fn parse_path<'i>(&mut self, scheme_type: SchemeType, has_host: &mut bool,
-                      path_start: usize, input: &'i str, context: Context)
+                      path_start: usize, input: &'i str)
                       -> &'i str {
         // Relative path state
         debug_assert!(self.serialization.ends_with("/"));
@@ -773,7 +771,7 @@ impl<'a> Parser<'a> {
                         end = i;
                         break
                     },
-                    '?' | '#' if context == Context::UrlParser => {
+                    '?' | '#' if self.context == Context::UrlParser => {
                         end = i;
                         break
                     },
@@ -893,7 +891,7 @@ impl<'a> Parser<'a> {
             Some('?') => {
                 query_start = Some(try!(to_u32(self.serialization.len())));
                 self.serialization.push('?');
-                let remaining = self.parse_query(scheme_end, &input[1..], Context::UrlParser);
+                let remaining = self.parse_query(scheme_end, &input[1..]);
                 if let Some(remaining) = remaining {
                     input = remaining
                 } else {
@@ -912,13 +910,13 @@ impl<'a> Parser<'a> {
         Ok((query_start, Some(fragment_start)))
     }
 
-    pub fn parse_query<'i>(&mut self, scheme_end: u32, input: &'i str, context: Context)
+    pub fn parse_query<'i>(&mut self, scheme_end: u32, input: &'i str)
                            -> Option<&'i str> {
         let mut query = String::new();  // FIXME: use a streaming decoder instead
         let mut remaining = None;
         for (i, c) in input.char_indices() {
             match c {
-                '#' if context == Context::UrlParser => {
+                '#' if self.context == Context::UrlParser => {
                     remaining = Some(&input[i..]);
                     break
                 },