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

Remove the redundant is_relative field.

Simon Sapin 10 лет назад
Родитель
Сommit
31bde79556
3 измененных файлов с 19 добавлено и 35 удалено
  1. 7 10
      src/lib.rs
  2. 9 21
      src/parser.rs
  3. 3 4
      src/slicing.rs

+ 7 - 10
src/lib.rs

@@ -157,7 +157,6 @@ pub mod form_urlencoded;
 #[cfg_attr(feature="heap_size", derive(HeapSizeOf))]
 pub struct Url {
     serialization: String,
-    non_relative: bool,
 
     // Components
     scheme_end: u32,  // Before ':'
@@ -166,7 +165,7 @@ pub struct Url {
     host_end: u32,
     host: HostInternal,
     port: Option<u16>,
-    path_start: u32,  // Before initial '/' if !non_relative
+    path_start: u32,  // Before initial '/', if any
     query_start: Option<u32>,  // Before '?', unlike Position::QueryStart
     fragment_start: Option<u32>,  // Before '#', unlike Position::FragmentStart
 }
@@ -208,7 +207,7 @@ impl Url {
         &self.serialization
     }
 
-    /// Return the scheme of this URL, as an ASCII string without the ':' delimiter.
+    /// Return the scheme of this URL, lower-cased, as an ASCII string without the ':' delimiter.
     #[inline]
     pub fn scheme(&self) -> &str {
         self.slice(..self.scheme_end)
@@ -217,7 +216,7 @@ impl Url {
     /// Return whether this URL is non-relative (typical of e.g. `data:` and `mailto:` URLs.)
     #[inline]
     pub fn non_relative(&self) -> bool {
-        self.non_relative
+        self.byte_at(self.path_start) != b'/'
     }
 
     /// Return the username for this URL (typically the empty string)
@@ -309,12 +308,11 @@ impl Url {
     ///
     /// Return `None` for non-relative URLs, or an iterator of at least one string.
     pub fn path_segments(&self) -> Option<str::Split<char>> {
-        if self.non_relative {
-            None
-        } else {
-            let path = self.path();
-            debug_assert!(path.starts_with("/"));
+        let path = self.path();
+        if path.starts_with('/') {
             Some(path[1..].split('/'))
+        } else {
+            None
         }
     }
 
@@ -354,7 +352,6 @@ impl Url {
         try!(path_to_file_url_segments(path.as_ref(), &mut serialization));
         Ok(Url {
             serialization: serialization,
-            non_relative: false,
             scheme_end: "file".len() as u32,
             username_end: path_start,
             host_start: path_start,

+ 9 - 21
src/parser.rs

@@ -142,7 +142,7 @@ impl<'a> Parser<'a> {
         if let Some(base_url) = self.base_url {
             if input.starts_with("#") {
                 self.fragment_only(base_url, input)
-            } else if base_url.non_relative {
+            } else if base_url.non_relative() {
                 Err(ParseError::RelativeUrlWithNonRelativeBase)
             } else {
                 let scheme_type = SchemeType::from(base_url.scheme());
@@ -204,7 +204,7 @@ impl<'a> Parser<'a> {
                     if slashes_count < 2 &&
                             base_url.scheme() == &self.serialization[..scheme_end as usize] {
                         // Non-relative URLs only happen with "not special" schemes.
-                        debug_assert!(!base_url.non_relative);
+                        debug_assert!(!base_url.non_relative());
                         self.serialization.clear();
                         return self.parse_relative(input, scheme_type, base_url)
                     }
@@ -231,15 +231,14 @@ impl<'a> Parser<'a> {
         let host_end = path_start;
         let host = HostInternal::None;
         let port = None;
-        let relative = input.starts_with("/");
-        let remaining = if relative {
+        let remaining = if input.starts_with("/") {
             let path_start = self.serialization.len();
             self.serialization.push('/');
             self.parse_path(scheme_type, &mut false, path_start, &input[1..])
         } else {
             self.parse_non_relative_path(input)
         };
-        self.with_query_and_fragment(!relative, scheme_end, username_end, host_start,
+        self.with_query_and_fragment(scheme_end, username_end, host_start,
                                      host_end, host, port, path_start, remaining)
     }
 
@@ -267,7 +266,6 @@ impl<'a> Parser<'a> {
                     let path_start = "file://".len() as u32;
                     Ok(Url {
                         serialization: self.serialization,
-                        non_relative: false,
                         scheme_end: scheme_end,
                         username_end: path_start,
                         host_start: path_start,
@@ -305,7 +303,6 @@ impl<'a> Parser<'a> {
                         try!(self.parse_query_and_fragment(scheme_end, input));
                     Ok(Url {
                         serialization: self.serialization,
-                        non_relative: false,
                         scheme_end: scheme_end,
                         username_end: path_start,
                         host_start: path_start,
@@ -329,7 +326,6 @@ impl<'a> Parser<'a> {
                     self.parse_fragment(&input[1..]);
                     Ok(Url {
                         serialization: self.serialization,
-                        non_relative: false,
                         scheme_end: scheme_end,
                         username_end: path_start,
                         host_start: path_start,
@@ -368,7 +364,6 @@ impl<'a> Parser<'a> {
                         try!(self.parse_query_and_fragment(scheme_end, remaining));
                     Ok(Url {
                         serialization: self.serialization,
-                        non_relative: false,
                         scheme_end: scheme_end,
                         username_end: host_start,
                         host_start: host_start,
@@ -398,7 +393,6 @@ impl<'a> Parser<'a> {
                     let path_start = path_start as u32;
                     Ok(Url {
                         serialization: self.serialization,
-                        non_relative: false,
                         scheme_end: scheme_end,
                         username_end: path_start,
                         host_start: path_start,
@@ -425,9 +419,8 @@ impl<'a> Parser<'a> {
                     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);
-                    let non_relative = false;
                     self.with_query_and_fragment(
-                        non_relative, base_url.scheme_end, base_url.username_end, base_url.host_start,
+                        base_url.scheme_end, base_url.username_end, base_url.host_start,
                         base_url.host_end, base_url.host, base_url.port, base_url.path_start, remaining)
                 } else {
                     self.serialization.push_str("file:///");
@@ -440,7 +433,6 @@ impl<'a> Parser<'a> {
                     let path_start = path_start as u32;
                     Ok(Url {
                         serialization: self.serialization,
-                        non_relative: false,
                         scheme_end: scheme_end,
                         username_end: path_start,
                         host_start: path_start,
@@ -506,9 +498,8 @@ impl<'a> Parser<'a> {
                 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..]);
-                let non_relative = false;
                 self.with_query_and_fragment(
-                    non_relative, base_url.scheme_end, base_url.username_end, base_url.host_start,
+                    base_url.scheme_end, base_url.username_end, base_url.host_start,
                     base_url.host_end, base_url.host, base_url.port, base_url.path_start, remaining)
             }
             _ => {
@@ -522,9 +513,8 @@ impl<'a> Parser<'a> {
                 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);
-                let non_relative = false;
                 self.with_query_and_fragment(
-                    non_relative, base_url.scheme_end, base_url.username_end, base_url.host_start,
+                    base_url.scheme_end, base_url.username_end, base_url.host_start,
                     base_url.host_end, base_url.host, base_url.port, base_url.path_start, remaining)
             }
         }
@@ -534,7 +524,6 @@ impl<'a> Parser<'a> {
                           -> ParseResult<Url> {
         self.serialization.push('/');
         self.serialization.push('/');
-        let non_relative = false;
         // authority state
         let (username_end, remaining) = try!(self.parse_userinfo(input, scheme_type));
         // host state
@@ -545,7 +534,7 @@ impl<'a> Parser<'a> {
         let path_start = try!(to_u32(self.serialization.len()));
         let remaining = self.parse_path_start(
             scheme_type, &mut true, remaining);
-        self.with_query_and_fragment(non_relative, scheme_end, username_end, host_start,
+        self.with_query_and_fragment(scheme_end, username_end, host_start,
                                      host_end, host, port, path_start, remaining)
     }
 
@@ -861,7 +850,7 @@ impl<'a> Parser<'a> {
         ""
     }
 
-    fn with_query_and_fragment(mut self, non_relative: bool, scheme_end: u32, username_end: u32,
+    fn with_query_and_fragment(mut self, scheme_end: u32, username_end: u32,
                                host_start: u32, host_end: u32, host: HostInternal,
                                port: Option<u16>, path_start: u32, remaining: &str)
                                -> ParseResult<Url> {
@@ -869,7 +858,6 @@ impl<'a> Parser<'a> {
             try!(self.parse_query_and_fragment(scheme_end, remaining));
         Ok(Url {
             serialization: self.serialization,
-            non_relative: non_relative,
             scheme_end: scheme_end,
             username_end: username_end,
             host_start: host_start,

+ 3 - 4
src/slicing.rs

@@ -104,13 +104,12 @@ impl Url {
 
             Position::AfterScheme => self.scheme_end as usize,
 
-            Position::BeforeUsername => if self.non_relative {
+            Position::BeforeUsername => if self.slice(self.scheme_end..).starts_with("://") {
+                self.scheme_end as usize + "://".len()
+            } else {
                 debug_assert!(self.byte_at(self.scheme_end) == b':');
                 debug_assert!(self.scheme_end + ":".len() as u32 == self.username_end);
                 self.scheme_end as usize + ":".len()
-            } else {
-                debug_assert!(self.slice(self.scheme_end..).starts_with("://"));
-                self.scheme_end as usize + "://".len()
             },
 
             Position::AfterUsername => self.username_end as usize,