Przeglądaj źródła

Fix/clarify comments, and add a debug_assert!

Simon Sapin 10 lat temu
rodzic
commit
cd9fda8e30
2 zmienionych plików z 14 dodań i 5 usunięć
  1. 9 2
      src/encoding.rs
  2. 5 3
      src/lib.rs

+ 9 - 2
src/encoding.rs

@@ -74,6 +74,7 @@ impl EncodingOverride {
 
     pub fn decode<'a>(&self, input: Cow<'a, [u8]>) -> Cow<'a, str> {
         match self.encoding {
+            // `encoding.decode` never returns `Err` when called with `DecoderTrap::Replace`
             Some(encoding) => encoding.decode(&input, DecoderTrap::Replace).unwrap().into(),
             None => decode_utf8_lossy(input),
         }
@@ -81,6 +82,7 @@ impl EncodingOverride {
 
     pub fn encode<'a>(&self, input: Cow<'a, str>) -> Cow<'a, [u8]> {
         match self.encoding {
+            // `encoding.encode` never returns `Err` when called with `EncoderTrap::NcrEscape`
             Some(encoding) => Cow::Owned(encoding.encode(&input, EncoderTrap::NcrEscape).unwrap()),
             None => encode_utf8(input)
         }
@@ -112,10 +114,15 @@ pub fn decode_utf8_lossy(input: Cow<[u8]>) -> Cow<str> {
     match input {
         Cow::Borrowed(bytes) => String::from_utf8_lossy(bytes),
         Cow::Owned(bytes) => {
+            let raw_utf8: *const [u8];
             match String::from_utf8_lossy(&bytes) {
-                Cow::Borrowed(_) => unsafe { String::from_utf8_unchecked(bytes) }.into(),
-                Cow::Owned(s) => s.into(),
+                Cow::Borrowed(utf8) => raw_utf8 = utf8.as_bytes(),
+                Cow::Owned(s) => return s.into(),
             }
+            // from_utf8_lossy returned a borrow of `bytes` unchanged.
+            debug_assert!(raw_utf8 == &*bytes as *const [u8]);
+            // Reuse the existing `Vec` allocation.
+            unsafe { String::from_utf8_unchecked(bytes) }.into()
         }
     }
 }

+ 5 - 3
src/lib.rs

@@ -503,9 +503,9 @@ impl Url {
     }
 
     /// Return the path for this URL, as a percent-encoded ASCII string.
-    /// For relative URLs, this starts with a '/' slash
-    /// and continues with slash-separated path segments.
     /// For cannot-be-a-base URLs, this is an arbitrary string that doesn’t start with '/'.
+    /// For other URLs, this starts with a '/' slash
+    /// and continues with slash-separated path segments.
     pub fn path(&self) -> &str {
         match (self.query_start, self.fragment_start) {
             (None, None) => self.slice(self.path_start..),
@@ -516,7 +516,8 @@ impl Url {
         }
     }
 
-    /// If this URL is relative, return an iterator of '/' slash-separated path segments,
+    /// Unless this URL is cannot-be-a-base,
+    /// return an iterator of '/' slash-separated path segments,
     /// each as a percent-encoded ASCII string.
     ///
     /// Return `None` for cannot-be-a-base URLs, or an iterator of at least one string.
@@ -718,6 +719,7 @@ impl Url {
     /// Remove the last segment of this URL’s path.
     ///
     /// If this URL is cannot-be-a-base, do nothing and return `Err`.
+    /// If this URL is not cannot-be-a-base and its path is `/`, do nothing and return `Ok`.
     pub fn pop_path_segment(&mut self) -> Result<(), ()> {
         if self.cannot_be_a_base() {
             return Err(())