Przeglądaj źródła

Use std::borrow::Cow instead of temporary parameter hack.

Simon Sapin 11 lat temu
rodzic
commit
9f05a01080
4 zmienionych plików z 14 dodań i 31 usunięć
  1. 11 25
      src/encoding.rs
  2. 1 2
      src/form_urlencoded.rs
  3. 1 2
      src/parser.rs
  4. 1 2
      src/punycode.rs

+ 11 - 25
src/encoding.rs

@@ -10,18 +10,13 @@
 //! Abstraction that conditionally compiles either to rust-encoding,
 //! or to only support UTF-8.
 
-#[cfg(feature = "query_encoding")]
-extern crate encoding;
-
-#[cfg(feature = "query_encoding")]
-use self::encoding::types::{DecoderTrap, EncoderTrap};
+#[cfg(feature = "query_encoding")] extern crate encoding;
 
-#[cfg(feature = "query_encoding")]
-use self::encoding::label::encoding_from_whatwg_label;
-
-#[cfg(feature = "query_encoding")]
-pub use self::encoding::types::EncodingRef;
+use std::borrow::Cow;
 
+#[cfg(feature = "query_encoding")] use self::encoding::types::{DecoderTrap, EncoderTrap};
+#[cfg(feature = "query_encoding")] use self::encoding::label::encoding_from_whatwg_label;
+#[cfg(feature = "query_encoding")] pub use self::encoding::types::EncodingRef;
 
 #[cfg(feature = "query_encoding")]
 pub struct EncodingOverride {
@@ -62,20 +57,11 @@ impl EncodingOverride {
         }
     }
 
-    // For UTF-8, we want to return the &[u8] bytes of the &str input strings without copying
-    // But for other encodings we have to allocate a new Vec<u8>.
-    // To return &[u8] in that case, the vector has to be kept somewhere
-    // that lives at least as long as the return value.
-    // Therefore, the caller provides a temporary Vec<u8> as scratch space.
-    //
-    // FIXME: Return std::borrow::Cow<'a, Vec<u8>, [u8]> instead.
-    pub fn encode<'a>(&self, input: &'a str, tmp: &'a mut Vec<u8>) -> &'a [u8] {
+    pub fn encode<'a>(&self, input: &'a str) -> Cow<'a, Vec<u8>, [u8]> {
         match self.encoding {
-            Some(encoding) => {
-                *tmp = encoding.encode(input.as_slice(), EncoderTrap::NcrEscape).unwrap();
-                tmp.as_slice()
-            },
-            None => input.as_bytes()  // UTF-8
+            Some(encoding) => Cow::Owned(
+                encoding.encode(input.as_slice(), EncoderTrap::NcrEscape).unwrap()),
+            None => Cow::Borrowed(input.as_bytes()),  // UTF-8
         }
     }
 }
@@ -102,7 +88,7 @@ impl EncodingOverride {
         String::from_utf8_lossy(input).into_string()
     }
 
-    pub fn encode<'a>(&self, input: &'a str, _: &'a mut Vec<u8>) -> &'a [u8] {
-        input.as_bytes()
+    pub fn encode<'a>(&self, input: &'a str) -> Cow<'a, Vec<u8>, [u8]> {
+        Cow::Borrowed(input.as_bytes())
     }
 }

+ 1 - 2
src/form_urlencoded.rs

@@ -123,8 +123,7 @@ fn serialize_internal<'a, I>(mut pairs: I, encoding_override: EncodingOverride)
     #[inline]
     fn byte_serialize(input: &str, output: &mut String,
                       encoding_override: EncodingOverride) {
-        let tmp = &mut vec![];
-        for &byte in encoding_override.encode(input, tmp).iter() {
+        for &byte in encoding_override.encode(input).iter() {
             if byte == b' ' {
                 output.push_str("+")
             } else {

+ 1 - 2
src/parser.rs

@@ -644,8 +644,7 @@ pub fn parse_query<'a>(input: &'a str, context: Context, parser: &UrlParser)
         }
     }
 
-    let tmp = &mut vec![];
-    let query_bytes = parser.query_encoding_override.encode(query.as_slice(), tmp);
+    let query_bytes = parser.query_encoding_override.encode(query.as_slice());
     Ok((percent_encode(query_bytes.as_slice(), QUERY_ENCODE_SET), remaining))
 }
 

+ 1 - 2
src/punycode.rs

@@ -15,7 +15,6 @@
 
 use std::u32;
 use std::char;
-use std::string;
 
 // Bootstring parameters for Punycode
 static BASE: u32 = 36;
@@ -144,7 +143,7 @@ pub fn encode(input: &[char]) -> Option<String> {
     let output_bytes = input.iter().filter_map(|&c|
         if c.is_ascii() { Some(c as u8) } else { None }
     ).collect();
-    let mut output = unsafe { string::raw::from_utf8(output_bytes) };
+    let mut output = unsafe { String::from_utf8_unchecked(output_bytes) };
     let basic_length = output.len() as u32;
     if basic_length > 0 {
         output.push_str("-")