From 503f52f3b67092bd7134e2fe3ca516918348ce76 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 24 Feb 2015 12:23:57 +0100 Subject: [PATCH] `form_urlencoded::serialize(...)` handles owned as well as borrowed pairs Related to #81 --- src/form_urlencoded.rs | 58 ++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/form_urlencoded.rs b/src/form_urlencoded.rs index 4e5a6911..6e6e74f3 100644 --- a/src/form_urlencoded.rs +++ b/src/form_urlencoded.rs @@ -13,6 +13,7 @@ //! Converts between a string (such as an URL’s query string) //! and a sequence of (name, value) pairs. +use std::borrow::Borrow; use std::ascii::AsciiExt; use encoding::EncodingOverride; use percent_encoding::{percent_encode_to, percent_decode, FORM_URLENCODED_ENCODE_SET}; @@ -97,7 +98,9 @@ pub fn serialize_owned(pairs: &[(String, String)]) -> String { /// Convert an iterator of (name, value) pairs /// into a string in the `application/x-www-form-urlencoded` format. #[inline] -pub fn serialize<'a, I>(pairs: I) -> String where I: Iterator { +pub fn serialize<'a, I, T>(pairs: I) -> String + where T: Borrow<(&'a str, &'a str)>, + I: Iterator { serialize_internal(pairs, EncodingOverride::utf8()) } @@ -112,14 +115,16 @@ pub fn serialize<'a, I>(pairs: I) -> String where I: Iterator(pairs: I, encoding_override: Option<::encoding::EncodingRef>) +pub fn serialize_with_encoding<'a, I, T>(pairs: I, encoding_override: Option<::encoding::EncodingRef>) -> String - where I: Iterator { + where T: Borrow<(&'a str, &'a str)>, + I: Iterator { serialize_internal(pairs, EncodingOverride::from_opt_encoding(encoding_override)) } -fn serialize_internal<'a, I>(pairs: I, encoding_override: EncodingOverride) -> String - where I: Iterator { +fn serialize_internal<'a, I, T>(pairs: I, encoding_override: EncodingOverride) -> String + where T: Borrow<(&'a str, &'a str)>, + I: Iterator { #[inline] fn byte_serialize(input: &str, output: &mut String, encoding_override: EncodingOverride) { @@ -133,7 +138,8 @@ fn serialize_internal<'a, I>(pairs: I, encoding_override: EncodingOverride) -> S } let mut output = String::new(); - for (name, value) in pairs { + for pair in pairs { + let &(name, value) = pair.borrow(); if output.len() > 0 { output.push_str("&"); } @@ -145,14 +151,34 @@ fn serialize_internal<'a, I>(pairs: I, encoding_override: EncodingOverride) -> S } -#[test] -fn test_form_urlencoded() { - let pairs = &[ - ("foo".to_string(), "é&".to_string()), - ("bar".to_string(), "".to_string()), - ("foo".to_string(), "#".to_string()) - ]; - let encoded = serialize_owned(pairs); - assert_eq!(encoded, "foo=%C3%A9%26&bar=&foo=%23"); - assert_eq!(parse(encoded.as_bytes()), pairs.to_vec()); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_form_urlencoded() { + let pairs = &[ + ("foo".to_string(), "é&".to_string()), + ("bar".to_string(), "".to_string()), + ("foo".to_string(), "#".to_string()) + ]; + let encoded = serialize_owned(pairs); + assert_eq!(encoded, "foo=%C3%A9%26&bar=&foo=%23"); + assert_eq!(parse(encoded.as_bytes()), pairs.to_vec()); + } + + #[test] + fn test_form_serialize() { + let pairs = [("foo", "é&"), + ("bar", ""), + ("foo", "#")]; + + let want = "foo=%C3%A9%26&bar=&foo=%23"; + // Works with referenced tuples + assert_eq!(serialize(pairs.iter()), want); + // Works with owned tuples + assert_eq!(serialize(pairs.iter().map(|p| (p.0, p.1))), want); + + } }