serde_qs/
ser.rs

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