serde_qs/
ser.rs

1//! Serialization support for querystrings.
2
3use percent_encoding::{percent_encode, AsciiSet, NON_ALPHANUMERIC};
4use serde::ser;
5
6use crate::error::*;
7
8use std::borrow::Cow;
9use std::fmt::Display;
10use std::io::Write;
11use std::str;
12
13const QS_ENCODE_SET: &AsciiSet = &NON_ALPHANUMERIC
14    .remove(b' ')
15    .remove(b'*')
16    .remove(b'-')
17    .remove(b'.')
18    .remove(b'_');
19
20/// Serializes a value into a querystring.
21///
22/// ```
23/// # #[macro_use]
24/// # extern crate serde_derive;
25/// # extern crate serde_qs;
26/// #[derive(Deserialize, Serialize)]
27/// struct Query {
28///     name: String,
29///     age: u8,
30///     occupation: String,
31/// }
32///
33/// # fn main(){
34/// let q =  Query {
35///     name: "Alice".to_owned(),
36///     age: 24,
37///     occupation: "Student".to_owned(),
38/// };
39///
40///
41/// assert_eq!(
42///     serde_qs::to_string(&q).unwrap(),
43///     "name=Alice&age=24&occupation=Student");
44/// # }
45/// ```
46pub fn to_string<T: ser::Serialize>(input: &T) -> Result<String> {
47    let mut buffer = Vec::new();
48    let mut first = true;
49    input.serialize(&mut QsSerializer {
50        writer: &mut buffer,
51        key: None,
52        first: &mut first,
53    })?;
54    String::from_utf8(buffer).map_err(Error::from)
55}
56
57/// Serializes a value into a generic writer object.
58///
59/// ```
60/// # #[macro_use]
61/// # extern crate serde_derive;
62/// # extern crate serde_qs;
63/// #[derive(Deserialize, Serialize)]
64/// struct Query {
65///     name: String,
66///     age: u8,
67///     occupation: String,
68/// }
69///
70/// # fn main(){
71/// let q =  Query {
72///     name: "Alice".to_owned(),
73///     age: 24,
74///     occupation: "Student".to_owned(),
75/// };
76///
77/// let mut buffer = Vec::new();
78/// serde_qs::to_writer(&q, &mut buffer).unwrap();
79/// assert_eq!(
80///     String::from_utf8(buffer).unwrap(),
81///     "name=Alice&age=24&occupation=Student");
82/// # }
83/// ```
84pub fn to_writer<T: ser::Serialize, W: Write>(input: &T, writer: &mut W) -> Result<()> {
85    let mut first = true;
86    input.serialize(&mut QsSerializer {
87        writer,
88        key: None,
89        first: &mut first,
90    })
91}
92
93/// A serializer for the querystring format.
94///
95/// * Supported top-level inputs are structs and maps.
96///
97/// * Supported values are currently most primitive types, structs, maps and
98///   sequences. Sequences are serialized with an incrementing key index.
99///
100/// * Newtype structs defer to their inner values.
101pub struct QsSerializer<'a, W: 'a + Write> {
102    key: Option<Cow<'static, str>>,
103    writer: &'a mut W,
104    first: &'a mut bool,
105}
106
107fn replace_space(input: &str) -> Cow<str> {
108    match input.as_bytes().iter().position(|&b| b == b' ') {
109        None => Cow::Borrowed(input),
110        Some(first_position) => {
111            let mut replaced = input.as_bytes().to_owned();
112            replaced[first_position] = b'+';
113            for byte in &mut replaced[first_position + 1..] {
114                if *byte == b' ' {
115                    *byte = b'+';
116                }
117            }
118            Cow::Owned(String::from_utf8(replaced).expect("replacing ' ' with '+' cannot panic"))
119        }
120    }
121}
122
123impl<'a, W: 'a + Write> QsSerializer<'a, W> {
124    fn extend_key(&mut self, newkey: &str) {
125        let newkey = percent_encode(newkey.as_bytes(), QS_ENCODE_SET)
126            .map(replace_space)
127            .collect::<String>();
128        let key = if let Some(ref key) = self.key {
129            format!("{}[{}]", key, newkey)
130        } else {
131            newkey
132        };
133        self.key = Some(Cow::Owned(key))
134    }
135
136    fn write_value(&mut self, value: &[u8]) -> Result<()> {
137        if let Some(ref key) = self.key {
138            write!(
139                self.writer,
140                "{}{}={}",
141                if *self.first {
142                    *self.first = false;
143                    ""
144                } else {
145                    "&"
146                },
147                key,
148                percent_encode(value, QS_ENCODE_SET)
149                    .map(replace_space)
150                    .collect::<String>()
151            )
152            .map_err(Error::from)
153        } else {
154            Err(Error::no_key())
155        }
156    }
157
158    /// Creates a new `QsSerializer` with a distinct key, but `writer` and
159    ///`first` referring to the original data.
160    fn new_from_ref<'b: 'a>(other: &'a mut QsSerializer<'b, W>) -> QsSerializer<'a, W> {
161        Self {
162            key: other.key.clone(),
163            writer: other.writer,
164            first: other.first,
165        }
166    }
167}
168
169impl Error {
170    fn no_key() -> Self {
171        let msg = "tried to serialize a value before serializing key";
172        Error::Custom(msg.into())
173    }
174}
175
176macro_rules! serialize_as_string {
177    (Qs $($ty:ty => $meth:ident,)*) => {
178        $(
179            fn $meth(self, v: $ty) -> Result<Self::Ok> {
180                self.write_value(&v.to_string().as_bytes())
181            }
182        )*
183    };
184    ($($ty:ty => $meth:ident,)*) => {
185        $(
186            fn $meth(self, v: $ty) -> Result<Self::Ok> {
187                Ok(v.to_string())
188            }
189        )*
190    };
191}
192
193impl<'a, W: Write> ser::Serializer for &'a mut QsSerializer<'a, W> {
194    type Ok = ();
195    type Error = Error;
196    type SerializeSeq = QsSeq<'a, W>;
197    type SerializeTuple = QsSeq<'a, W>;
198    type SerializeTupleStruct = QsSeq<'a, W>;
199    type SerializeTupleVariant = QsSeq<'a, W>;
200    type SerializeMap = QsMap<'a, W>;
201    type SerializeStruct = Self;
202    type SerializeStructVariant = Self;
203
204    serialize_as_string! {
205        Qs
206        bool => serialize_bool,
207        u8  => serialize_u8,
208        u16 => serialize_u16,
209        u32 => serialize_u32,
210        u64 => serialize_u64,
211        i8  => serialize_i8,
212        i16 => serialize_i16,
213        i32 => serialize_i32,
214        i64 => serialize_i64,
215        f32 => serialize_f32,
216        f64 => serialize_f64,
217        char => serialize_char,
218        &str => serialize_str,
219    }
220
221    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
222        self.write_value(value)
223    }
224
225    fn serialize_unit(self) -> Result<Self::Ok> {
226        self.write_value(&[])
227    }
228
229    /// Returns an error.
230    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
231        self.write_value(name.as_bytes())
232    }
233
234    /// Returns an error.
235    fn serialize_unit_variant(
236        self,
237        _name: &'static str,
238        _variant_index: u32,
239        variant: &'static str,
240    ) -> Result<Self::Ok> {
241        self.write_value(variant.as_bytes())
242    }
243
244    /// Returns an error.
245    fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
246        self,
247        _name: &'static str,
248        value: &T,
249    ) -> Result<Self::Ok> {
250        value.serialize(self)
251    }
252
253    /// Returns an error.
254    fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
255        self,
256        _name: &'static str,
257        _variant_index: u32,
258        variant: &'static str,
259        value: &T,
260    ) -> Result<Self::Ok> {
261        self.extend_key(variant);
262        value.serialize(self)
263    }
264
265    fn serialize_none(self) -> Result<Self::Ok> {
266        Ok(())
267    }
268
269    fn serialize_some<T: ?Sized + ser::Serialize>(self, value: &T) -> Result<Self::Ok> {
270        // Err(Error::Unsupported)
271        value.serialize(self)
272    }
273
274    /// Returns an error.
275    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
276        Ok(QsSeq(self, 0))
277    }
278
279    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
280        Ok(QsSeq(self, 0))
281    }
282
283    /// Returns an error.
284    fn serialize_tuple_struct(
285        self,
286        _name: &'static str,
287        _len: usize,
288    ) -> Result<Self::SerializeTupleStruct> {
289        Ok(QsSeq(self, 0))
290    }
291
292    fn serialize_tuple_variant(
293        self,
294        _name: &'static str,
295        _variant_index: u32,
296        variant: &'static str,
297        _len: usize,
298    ) -> Result<Self::SerializeTupleVariant> {
299        // self.write(variant)?;
300        self.extend_key(variant);
301        Ok(QsSeq(self, 0))
302    }
303
304    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
305        Ok(QsMap(self, None))
306    }
307
308    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
309        Ok(self)
310    }
311
312    fn serialize_struct_variant(
313        self,
314        _name: &'static str,
315        _variant_index: u32,
316        variant: &'static str,
317        _len: usize,
318    ) -> Result<Self::SerializeStructVariant> {
319        self.extend_key(variant);
320        Ok(self)
321    }
322}
323
324impl ser::Error for Error {
325    fn custom<T>(msg: T) -> Self
326    where
327        T: Display,
328    {
329        Error::Custom(msg.to_string())
330    }
331}
332
333pub struct QsSeq<'a, W: 'a + Write>(&'a mut QsSerializer<'a, W>, usize);
334pub struct QsMap<'a, W: 'a + Write>(&'a mut QsSerializer<'a, W>, Option<Cow<'a, str>>);
335
336impl<'a, W: Write> ser::SerializeTuple for QsSeq<'a, W> {
337    type Ok = ();
338    type Error = Error;
339    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
340    where
341        T: ser::Serialize,
342    {
343        let mut serializer = QsSerializer::new_from_ref(self.0);
344        serializer.extend_key(&self.1.to_string());
345        self.1 += 1;
346        value.serialize(&mut serializer)
347    }
348
349    fn end(self) -> Result<Self::Ok> {
350        Ok(())
351    }
352}
353
354impl<'a, W: Write> ser::SerializeSeq for QsSeq<'a, W> {
355    type Ok = ();
356    type Error = Error;
357    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
358    where
359        T: ser::Serialize,
360    {
361        let mut serializer = QsSerializer::new_from_ref(self.0);
362        serializer.extend_key(&self.1.to_string());
363        self.1 += 1;
364        value.serialize(&mut serializer)
365    }
366    fn end(self) -> Result<Self::Ok> {
367        Ok(())
368    }
369}
370
371impl<'a, W: Write> ser::SerializeStruct for &'a mut QsSerializer<'a, W> {
372    type Ok = ();
373    type Error = Error;
374    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
375    where
376        T: ser::Serialize,
377    {
378        let mut serializer = QsSerializer::new_from_ref(self);
379        serializer.extend_key(key);
380        value.serialize(&mut serializer)
381    }
382    fn end(self) -> Result<Self::Ok> {
383        Ok(())
384    }
385}
386
387impl<'a, W: Write> ser::SerializeStructVariant for &'a mut QsSerializer<'a, W> {
388    type Ok = ();
389    type Error = Error;
390
391    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
392    where
393        T: ser::Serialize,
394    {
395        let mut serializer = QsSerializer::new_from_ref(self);
396        serializer.extend_key(key);
397        value.serialize(&mut serializer)
398    }
399
400    fn end(self) -> Result<Self::Ok> {
401        Ok(())
402    }
403}
404
405impl<'a, W: Write> ser::SerializeTupleVariant for QsSeq<'a, W> {
406    type Ok = ();
407    type Error = Error;
408
409    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
410    where
411        T: ser::Serialize,
412    {
413        let mut serializer = QsSerializer::new_from_ref(self.0);
414        serializer.extend_key(&self.1.to_string());
415        self.1 += 1;
416        value.serialize(&mut serializer)
417    }
418
419    fn end(self) -> Result<Self::Ok> {
420        Ok(())
421    }
422}
423
424impl<'a, W: Write> ser::SerializeTupleStruct for QsSeq<'a, W> {
425    type Ok = ();
426    type Error = Error;
427
428    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
429    where
430        T: ser::Serialize,
431    {
432        let mut serializer = QsSerializer::new_from_ref(self.0);
433        serializer.extend_key(&self.1.to_string());
434        self.1 += 1;
435        value.serialize(&mut serializer)
436    }
437
438    fn end(self) -> Result<Self::Ok> {
439        Ok(())
440    }
441}
442
443impl<'a, W: Write> ser::SerializeMap for QsMap<'a, W> {
444    type Ok = ();
445    type Error = Error;
446
447    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
448    where
449        T: ser::Serialize,
450    {
451        self.1 = Some(Cow::from(key.serialize(StringSerializer)?));
452        Ok(())
453    }
454
455    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
456    where
457        T: ser::Serialize,
458    {
459        let mut serializer = QsSerializer::new_from_ref(self.0);
460        if let Some(ref key) = self.1 {
461            serializer.extend_key(key);
462        } else {
463            return Err(Error::no_key());
464        }
465        self.1 = None;
466        value.serialize(&mut serializer)
467    }
468
469    fn end(self) -> Result<Self::Ok> {
470        Ok(())
471    }
472
473    fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()>
474    where
475        K: ser::Serialize,
476        V: ser::Serialize,
477    {
478        let mut serializer = QsSerializer::new_from_ref(self.0);
479        serializer.extend_key(&key.serialize(StringSerializer)?);
480        value.serialize(&mut serializer)
481    }
482}
483
484struct StringSerializer;
485
486impl ser::Serializer for StringSerializer {
487    type Ok = String;
488    type Error = Error;
489    type SerializeSeq = ser::Impossible<String, Error>;
490    type SerializeTuple = ser::Impossible<String, Error>;
491    type SerializeTupleStruct = ser::Impossible<String, Error>;
492    type SerializeTupleVariant = ser::Impossible<String, Error>;
493    type SerializeMap = ser::Impossible<String, Error>;
494    type SerializeStruct = ser::Impossible<String, Error>;
495    type SerializeStructVariant = ser::Impossible<String, Error>;
496
497    serialize_as_string! {
498        bool => serialize_bool,
499        u8  => serialize_u8,
500        u16 => serialize_u16,
501        u32 => serialize_u32,
502        u64 => serialize_u64,
503        i8  => serialize_i8,
504        i16 => serialize_i16,
505        i32 => serialize_i32,
506        i64 => serialize_i64,
507        f32 => serialize_f32,
508        f64 => serialize_f64,
509        char => serialize_char,
510        &str => serialize_str,
511    }
512
513    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
514        Ok(String::from_utf8_lossy(value).to_string())
515    }
516
517    /// Returns an error.
518    fn serialize_unit(self) -> Result<Self::Ok> {
519        Err(Error::Unsupported)
520    }
521
522    /// Returns an error.
523    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
524        Err(Error::Unsupported)
525    }
526
527    fn serialize_unit_variant(
528        self,
529        _name: &'static str,
530        _variant_index: u32,
531        variant: &'static str,
532    ) -> Result<Self::Ok> {
533        Ok(variant.to_string())
534    }
535
536    /// Returns an error.
537    fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
538        self,
539        _name: &'static str,
540        _value: &T,
541    ) -> Result<Self::Ok> {
542        Err(Error::Unsupported)
543    }
544
545    /// Returns an error.
546    fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
547        self,
548        _name: &'static str,
549        _variant_index: u32,
550        _variant: &'static str,
551        _value: &T,
552    ) -> Result<Self::Ok> {
553        Err(Error::Unsupported)
554    }
555
556    /// Returns an error.
557    fn serialize_none(self) -> Result<Self::Ok> {
558        Err(Error::Unsupported)
559    }
560
561    /// Returns an error.
562    fn serialize_some<T: ?Sized + ser::Serialize>(self, _value: &T) -> Result<Self::Ok> {
563        Err(Error::Unsupported)
564    }
565
566    /// Returns an error.
567    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
568        Err(Error::Unsupported)
569    }
570
571    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
572        Err(Error::Unsupported)
573    }
574
575    /// Returns an error.
576    fn serialize_tuple_struct(
577        self,
578        _name: &'static str,
579        _len: usize,
580    ) -> Result<Self::SerializeTupleStruct> {
581        Err(Error::Unsupported)
582    }
583
584    fn serialize_tuple_variant(
585        self,
586        _name: &'static str,
587        _variant_index: u32,
588        _variant: &'static str,
589        _len: usize,
590    ) -> Result<Self::SerializeTupleVariant> {
591        Err(Error::Unsupported)
592    }
593
594    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
595        Err(Error::Unsupported)
596    }
597
598    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
599        Err(Error::Unsupported)
600    }
601
602    fn serialize_struct_variant(
603        self,
604        _name: &'static str,
605        _variant_index: u32,
606        _variant: &'static str,
607        _len: usize,
608    ) -> Result<Self::SerializeStructVariant> {
609        Err(Error::Unsupported)
610    }
611}