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                amp.then_some("&").unwrap_or_default(),
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!(
298                self.writer,
299                "{}{}=",
300                amp.then_some("&").unwrap_or_default(),
301                key,
302            )
303            .map_err(Error::from)
304        } else {
305            // For top level unit types
306            write!(self.writer, "{}", amp.then_some("&").unwrap_or_default(),).map_err(Error::from)
307        }
308    }
309
310    /// Creates a new `QsSerializer` with a distinct key, but `writer` and
311    ///`first` referring to the original data.
312    fn new_from_ref<'b: 'a>(other: &'a mut QsSerializer<'b, W>) -> QsSerializer<'a, W> {
313        Self {
314            key: other.key.clone(),
315            writer: other.writer,
316            first: other.first.clone(),
317        }
318    }
319}
320
321impl Error {
322    fn no_key() -> Self {
323        let msg = "tried to serialize a value before serializing key";
324        Error::Custom(msg.into())
325    }
326}
327
328impl<'a, W: Write> ser::Serializer for QsSerializer<'a, W> {
329    type Ok = ();
330    type Error = Error;
331    type SerializeSeq = QsSeq<'a, W>;
332    type SerializeTuple = QsSeq<'a, W>;
333    type SerializeTupleStruct = QsSeq<'a, W>;
334    type SerializeTupleVariant = QsSeq<'a, W>;
335    type SerializeMap = QsMap<'a, W>;
336    type SerializeStruct = Self;
337    type SerializeStructVariant = Self;
338
339    serialize_as_string! {
340        Qs
341        bool => serialize_bool,
342        u8  => serialize_u8,
343        u16 => serialize_u16,
344        u32 => serialize_u32,
345        u64 => serialize_u64,
346        i8  => serialize_i8,
347        i16 => serialize_i16,
348        i32 => serialize_i32,
349        i64 => serialize_i64,
350        f32 => serialize_f32,
351        f64 => serialize_f64,
352        char => serialize_char,
353        &str => serialize_str,
354    }
355
356    fn serialize_bytes(mut self, value: &[u8]) -> Result<Self::Ok> {
357        self.write_value(value)
358    }
359
360    fn serialize_unit(mut self) -> Result<Self::Ok> {
361        self.write_unit()
362    }
363
364    fn serialize_unit_struct(mut self, _: &'static str) -> Result<Self::Ok> {
365        self.write_unit()
366    }
367
368    fn serialize_unit_variant(
369        mut self,
370        _name: &'static str,
371        _variant_index: u32,
372        variant: &'static str,
373    ) -> Result<Self::Ok> {
374        self.write_value(variant.as_bytes())
375    }
376
377    fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
378        self,
379        _name: &'static str,
380        value: &T,
381    ) -> Result<Self::Ok> {
382        value.serialize(self)
383    }
384
385    fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
386        mut self,
387        _name: &'static str,
388        _variant_index: u32,
389        variant: &'static str,
390        value: &T,
391    ) -> Result<Self::Ok> {
392        self.extend_key(variant);
393        value.serialize(self)
394    }
395
396    fn serialize_none(self) -> Result<Self::Ok> {
397        Ok(())
398    }
399
400    fn serialize_some<T: ?Sized + ser::Serialize>(self, value: &T) -> Result<Self::Ok> {
401        value.serialize(self)
402    }
403
404    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
405        Ok(QsSeq(self, 0))
406    }
407
408    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
409        Ok(QsSeq(self, 0))
410    }
411
412    fn serialize_tuple_struct(
413        self,
414        _name: &'static str,
415        _len: usize,
416    ) -> Result<Self::SerializeTupleStruct> {
417        Ok(QsSeq(self, 0))
418    }
419
420    fn serialize_tuple_variant(
421        mut self,
422        _name: &'static str,
423        _variant_index: u32,
424        variant: &'static str,
425        _len: usize,
426    ) -> Result<Self::SerializeTupleVariant> {
427        self.extend_key(variant);
428        Ok(QsSeq(self, 0))
429    }
430
431    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
432        Ok(QsMap(self, None))
433    }
434
435    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
436        Ok(self)
437    }
438
439    fn serialize_struct_variant(
440        mut self,
441        _name: &'static str,
442        _variant_index: u32,
443        variant: &'static str,
444        _len: usize,
445    ) -> Result<Self::SerializeStructVariant> {
446        self.extend_key(variant);
447        Ok(self)
448    }
449}
450
451impl ser::Error for Error {
452    fn custom<T>(msg: T) -> Self
453    where
454        T: Display,
455    {
456        Error::Custom(msg.to_string())
457    }
458}
459
460#[doc(hidden)]
461pub struct QsSeq<'a, W: 'a + Write>(QsSerializer<'a, W>, usize);
462
463#[doc(hidden)]
464pub struct QsMap<'a, W: 'a + Write>(QsSerializer<'a, W>, Option<Cow<'a, str>>);
465
466impl<'a, W: Write> ser::SerializeTuple for QsSeq<'a, W> {
467    type Ok = ();
468    type Error = Error;
469    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
470    where
471        T: ser::Serialize,
472    {
473        let key = self.1.to_string();
474        self.1 += 1;
475        let mut serializer = QsSerializer::new_from_ref(&mut self.0);
476        serializer.extend_key(&key);
477        value.serialize(serializer)
478    }
479
480    fn end(self) -> Result<Self::Ok> {
481        Ok(())
482    }
483}
484
485impl<'a, W: Write> ser::SerializeSeq for QsSeq<'a, W> {
486    type Ok = ();
487    type Error = Error;
488    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
489    where
490        T: ser::Serialize,
491    {
492        let mut serializer = QsSerializer::new_from_ref(&mut self.0);
493        serializer.extend_key(&self.1.to_string());
494        self.1 += 1;
495        value.serialize(serializer)
496    }
497    fn end(self) -> Result<Self::Ok> {
498        Ok(())
499    }
500}
501
502impl<'a, W: Write> ser::SerializeStruct for QsSerializer<'a, W> {
503    type Ok = ();
504    type Error = Error;
505    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
506    where
507        T: ser::Serialize,
508    {
509        let mut serializer = QsSerializer::new_from_ref(self);
510        serializer.extend_key(key);
511        value.serialize(serializer)
512    }
513    fn end(self) -> Result<Self::Ok> {
514        Ok(())
515    }
516}
517
518impl<'a, W: Write> ser::SerializeStructVariant for QsSerializer<'a, W> {
519    type Ok = ();
520    type Error = Error;
521
522    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
523    where
524        T: ser::Serialize,
525    {
526        let mut serializer = QsSerializer::new_from_ref(self);
527        serializer.extend_key(key);
528        value.serialize(serializer)
529    }
530
531    fn end(self) -> Result<Self::Ok> {
532        Ok(())
533    }
534}
535
536impl<'a, W: Write> ser::SerializeTupleVariant for QsSeq<'a, W> {
537    type Ok = ();
538    type Error = Error;
539
540    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
541    where
542        T: ser::Serialize,
543    {
544        let mut serializer = QsSerializer::new_from_ref(&mut self.0);
545        serializer.extend_key(&self.1.to_string());
546        self.1 += 1;
547        value.serialize(serializer)
548    }
549
550    fn end(self) -> Result<Self::Ok> {
551        Ok(())
552    }
553}
554
555impl<'a, W: Write> ser::SerializeTupleStruct for QsSeq<'a, W> {
556    type Ok = ();
557    type Error = Error;
558
559    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
560    where
561        T: ser::Serialize,
562    {
563        let mut serializer = QsSerializer::new_from_ref(&mut self.0);
564        serializer.extend_key(&self.1.to_string());
565        self.1 += 1;
566        value.serialize(serializer)
567    }
568
569    fn end(self) -> Result<Self::Ok> {
570        Ok(())
571    }
572}
573
574impl<'a, W: Write> ser::SerializeMap for QsMap<'a, W> {
575    type Ok = ();
576    type Error = Error;
577
578    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
579    where
580        T: ser::Serialize,
581    {
582        self.1 = Some(Cow::from(key.serialize(StringSerializer)?));
583        Ok(())
584    }
585
586    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
587    where
588        T: ser::Serialize,
589    {
590        let mut serializer = QsSerializer::new_from_ref(&mut self.0);
591        if let Some(ref key) = self.1 {
592            serializer.extend_key(key);
593        } else {
594            return Err(Error::no_key());
595        }
596        self.1 = None;
597        value.serialize(serializer)
598    }
599
600    fn end(self) -> Result<Self::Ok> {
601        Ok(())
602    }
603
604    fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()>
605    where
606        K: ser::Serialize,
607        V: ser::Serialize,
608    {
609        let mut serializer = QsSerializer::new_from_ref(&mut self.0);
610        serializer.extend_key(&key.serialize(StringSerializer)?);
611        value.serialize(serializer)
612    }
613}
614
615struct StringSerializer;
616
617impl ser::Serializer for StringSerializer {
618    type Ok = String;
619    type Error = Error;
620    type SerializeSeq = ser::Impossible<String, Error>;
621    type SerializeTuple = ser::Impossible<String, Error>;
622    type SerializeTupleStruct = ser::Impossible<String, Error>;
623    type SerializeTupleVariant = ser::Impossible<String, Error>;
624    type SerializeMap = ser::Impossible<String, Error>;
625    type SerializeStruct = ser::Impossible<String, Error>;
626    type SerializeStructVariant = ser::Impossible<String, Error>;
627
628    serialize_as_string! {
629        bool => serialize_bool,
630        u8  => serialize_u8,
631        u16 => serialize_u16,
632        u32 => serialize_u32,
633        u64 => serialize_u64,
634        i8  => serialize_i8,
635        i16 => serialize_i16,
636        i32 => serialize_i32,
637        i64 => serialize_i64,
638        f32 => serialize_f32,
639        f64 => serialize_f64,
640        char => serialize_char,
641        &str => serialize_str,
642    }
643
644    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
645        Ok(String::from_utf8_lossy(value).to_string())
646    }
647
648    /// Returns an error.
649    fn serialize_unit(self) -> Result<Self::Ok> {
650        Err(Error::Unsupported)
651    }
652
653    /// Returns an error.
654    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
655        Err(Error::Unsupported)
656    }
657
658    fn serialize_unit_variant(
659        self,
660        _name: &'static str,
661        _variant_index: u32,
662        variant: &'static str,
663    ) -> Result<Self::Ok> {
664        Ok(variant.to_string())
665    }
666
667    /// Returns an error.
668    fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
669        self,
670        _name: &'static str,
671        _value: &T,
672    ) -> Result<Self::Ok> {
673        Err(Error::Unsupported)
674    }
675
676    /// Returns an error.
677    fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
678        self,
679        _name: &'static str,
680        _variant_index: u32,
681        _variant: &'static str,
682        _value: &T,
683    ) -> Result<Self::Ok> {
684        Err(Error::Unsupported)
685    }
686
687    /// Returns an error.
688    fn serialize_none(self) -> Result<Self::Ok> {
689        Err(Error::Unsupported)
690    }
691
692    /// Returns an error.
693    fn serialize_some<T: ?Sized + ser::Serialize>(self, _value: &T) -> Result<Self::Ok> {
694        Err(Error::Unsupported)
695    }
696
697    /// Returns an error.
698    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
699        Err(Error::Unsupported)
700    }
701
702    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
703        Err(Error::Unsupported)
704    }
705
706    /// Returns an error.
707    fn serialize_tuple_struct(
708        self,
709        _name: &'static str,
710        _len: usize,
711    ) -> Result<Self::SerializeTupleStruct> {
712        Err(Error::Unsupported)
713    }
714
715    fn serialize_tuple_variant(
716        self,
717        _name: &'static str,
718        _variant_index: u32,
719        _variant: &'static str,
720        _len: usize,
721    ) -> Result<Self::SerializeTupleVariant> {
722        Err(Error::Unsupported)
723    }
724
725    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
726        Err(Error::Unsupported)
727    }
728
729    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
730        Err(Error::Unsupported)
731    }
732
733    fn serialize_struct_variant(
734        self,
735        _name: &'static str,
736        _variant_index: u32,
737        _variant: &'static str,
738        _len: usize,
739    ) -> Result<Self::SerializeStructVariant> {
740        Err(Error::Unsupported)
741    }
742}