Skip to main content

simd_json/serde/
se.rs

1mod pp;
2use crate::{Error, ErrorType};
3pub use pp::*;
4use serde_ext::ser;
5use std::io::Write;
6use std::str;
7use value_trait::generator::BaseGenerator;
8
9macro_rules! iomap {
10    ($e:expr_2021) => {
11        ($e).map_err(|err| Error::generic(ErrorType::Io(err)))
12    };
13}
14
15/// Write a value to a vector
16/// # Errors
17/// when the data can not be written
18#[cfg_attr(not(feature = "no-inline"), inline)]
19pub fn to_vec<T>(to: &T) -> crate::Result<Vec<u8>>
20where
21    T: ser::Serialize + ?Sized,
22{
23    let v = Vec::with_capacity(512);
24    let mut s = Serializer(v);
25    to.serialize(&mut s).map(|()| s.0)
26}
27
28/// Write a value to a string
29///
30/// # Errors
31/// when the data can not be written
32#[cfg_attr(not(feature = "no-inline"), inline)]
33pub fn to_string<T>(to: &T) -> crate::Result<String>
34where
35    T: ser::Serialize + ?Sized,
36{
37    to_vec(to).map(|v| unsafe { String::from_utf8_unchecked(v) })
38}
39
40/// Write a value to a string
41/// # Errors
42/// when the data can not be written
43#[cfg_attr(not(feature = "no-inline"), inline)]
44pub fn to_writer<T, W>(writer: W, to: &T) -> crate::Result<()>
45where
46    T: ser::Serialize + ?Sized,
47    W: Write,
48{
49    let mut s = Serializer(writer);
50    to.serialize(&mut s)
51}
52struct Serializer<W: Write>(W);
53
54impl<W> BaseGenerator for Serializer<W>
55where
56    W: Write,
57{
58    type T = W;
59    #[cfg_attr(not(feature = "no-inline"), inline)]
60    fn get_writer(&mut self) -> &mut Self::T {
61        &mut self.0
62    }
63    #[cfg_attr(not(feature = "no-inline"), inline)]
64    fn write_min(&mut self, _slice: &[u8], min: u8) -> std::io::Result<()> {
65        self.0.write_all(&[min])
66    }
67}
68struct SerializeSeq<'serializer, W: Write + 'serializer> {
69    s: &'serializer mut Serializer<W>,
70    first: bool,
71}
72impl<W> ser::SerializeSeq for SerializeSeq<'_, W>
73where
74    W: Write,
75{
76    type Ok = ();
77    type Error = Error;
78    #[cfg_attr(not(feature = "no-inline"), inline)]
79    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
80    where
81        T: ?Sized + serde_ext::Serialize,
82    {
83        let SerializeSeq {
84            ref mut s,
85            ref mut first,
86            ..
87        } = *self;
88        if *first {
89            *first = false;
90            value.serialize(&mut **s)
91        } else {
92            iomap!(s.write(b",")).and_then(|()| value.serialize(&mut **s))
93        }
94    }
95    #[cfg_attr(not(feature = "no-inline"), inline)]
96    fn end(self) -> Result<Self::Ok, Self::Error> {
97        iomap!(self.s.write(b"]"))
98    }
99}
100
101impl<W> ser::SerializeTuple for SerializeSeq<'_, W>
102where
103    W: Write,
104{
105    type Ok = ();
106    type Error = Error;
107    #[cfg_attr(not(feature = "no-inline"), inline)]
108    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
109    where
110        T: ?Sized + serde_ext::Serialize,
111    {
112        let SerializeSeq {
113            ref mut s,
114            ref mut first,
115        } = *self;
116        if *first {
117            *first = false;
118            value.serialize(&mut **s)
119        } else {
120            iomap!(s.write(b",")).and_then(|()| value.serialize(&mut **s))
121        }
122    }
123    #[cfg_attr(not(feature = "no-inline"), inline)]
124    fn end(self) -> Result<Self::Ok, Self::Error> {
125        iomap!(self.s.write(b"]"))
126    }
127}
128
129impl<W> ser::SerializeTupleStruct for SerializeSeq<'_, W>
130where
131    W: Write,
132{
133    type Ok = ();
134    type Error = Error;
135    #[cfg_attr(not(feature = "no-inline"), inline)]
136    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
137    where
138        T: ?Sized + serde_ext::Serialize,
139    {
140        let SerializeSeq {
141            ref mut s,
142            ref mut first,
143        } = *self;
144        if *first {
145            *first = false;
146            value.serialize(&mut **s)
147        } else {
148            iomap!(s.write(b",")).and_then(|()| value.serialize(&mut **s))
149        }
150    }
151    #[cfg_attr(not(feature = "no-inline"), inline)]
152    fn end(self) -> Result<Self::Ok, Self::Error> {
153        iomap!(self.s.write(b"]"))
154    }
155}
156
157impl<W> ser::SerializeTupleVariant for SerializeSeq<'_, W>
158where
159    W: Write,
160{
161    type Ok = ();
162    type Error = Error;
163    #[cfg_attr(not(feature = "no-inline"), inline)]
164    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
165    where
166        T: ?Sized + serde_ext::Serialize,
167    {
168        let SerializeSeq {
169            ref mut s,
170            ref mut first,
171        } = *self;
172        if *first {
173            *first = false;
174            value.serialize(&mut **s)
175        } else {
176            iomap!(s.write(b",")).and_then(|()| value.serialize(&mut **s))
177        }
178    }
179    #[cfg_attr(not(feature = "no-inline"), inline)]
180    fn end(self) -> Result<Self::Ok, Self::Error> {
181        iomap!(self.s.write(b"]}"))
182    }
183}
184
185struct SerializeMap<'serializer, W: Write + 'serializer> {
186    s: &'serializer mut Serializer<W>,
187    first: bool,
188}
189
190impl<W> ser::SerializeMap for SerializeMap<'_, W>
191where
192    W: Write,
193{
194    type Ok = ();
195    type Error = Error;
196    #[cfg_attr(not(feature = "no-inline"), inline)]
197    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
198    where
199        T: ?Sized + serde_ext::Serialize,
200    {
201        let SerializeMap {
202            ref mut s,
203            ref mut first,
204            ..
205        } = *self;
206
207        if *first {
208            *first = false;
209            key.serialize(MapKeySerializer { s: &mut **s })
210                .and_then(|()| iomap!(s.write(b":")))
211        } else {
212            iomap!(s.write(b","))
213                .and_then(|()| key.serialize(MapKeySerializer { s: &mut **s }))
214                .and_then(|()| iomap!(s.write(b":")))
215        }
216    }
217    #[cfg_attr(not(feature = "no-inline"), inline)]
218    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
219    where
220        T: ?Sized + serde_ext::Serialize,
221    {
222        let SerializeMap { ref mut s, .. } = *self;
223        value.serialize(&mut **s)
224    }
225    #[cfg_attr(not(feature = "no-inline"), inline)]
226    fn end(self) -> Result<Self::Ok, Self::Error> {
227        iomap!(self.s.write(b"}"))
228    }
229}
230
231fn key_must_be_a_string() -> Error {
232    Error::generic(ErrorType::KeyMustBeAString)
233}
234
235struct MapKeySerializer<'serializer, W: Write + 'serializer> {
236    s: &'serializer mut Serializer<W>,
237}
238
239impl<W> ser::Serializer for MapKeySerializer<'_, W>
240where
241    W: Write,
242{
243    type Ok = ();
244    type Error = Error;
245
246    #[cfg_attr(not(feature = "no-inline"), inline)]
247    fn serialize_str(self, value: &str) -> Result<(), Self::Error> {
248        self.s.serialize_str(value)
249    }
250
251    #[cfg_attr(not(feature = "no-inline"), inline)]
252    fn serialize_unit_variant(
253        self,
254        _name: &'static str,
255        _variant_index: u32,
256        variant: &'static str,
257    ) -> Result<(), Self::Error> {
258        self.s.serialize_str(variant)
259    }
260
261    #[cfg_attr(not(feature = "no-inline"), inline)]
262    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<(), Self::Error>
263    where
264        T: ?Sized + serde_ext::Serialize,
265    {
266        value.serialize(self)
267    }
268
269    type SerializeSeq = ser::Impossible<(), Error>;
270    type SerializeTuple = ser::Impossible<(), Error>;
271    type SerializeTupleStruct = ser::Impossible<(), Error>;
272    type SerializeTupleVariant = ser::Impossible<(), Error>;
273    type SerializeMap = ser::Impossible<(), Error>;
274    type SerializeStruct = ser::Impossible<(), Error>;
275    type SerializeStructVariant = ser::Impossible<(), Error>;
276
277    fn serialize_bool(self, _value: bool) -> Result<(), Self::Error> {
278        Err(key_must_be_a_string())
279    }
280
281    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
282        iomap!(
283            self.s
284                .write_char(b'"')
285                .and_then(|()| self.s.write_int(v))
286                .and_then(|()| self.s.write_char(b'"'))
287        )
288    }
289
290    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
291        iomap!(
292            self.s
293                .write_char(b'"')
294                .and_then(|()| self.s.write_int(v))
295                .and_then(|()| self.s.write_char(b'"'))
296        )
297    }
298
299    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
300        iomap!(
301            self.s
302                .write_char(b'"')
303                .and_then(|()| self.s.write_int(v))
304                .and_then(|()| self.s.write_char(b'"'))
305        )
306    }
307
308    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
309        iomap!(
310            self.s
311                .write_char(b'"')
312                .and_then(|()| self.s.write_int(v))
313                .and_then(|()| self.s.write_char(b'"'))
314        )
315    }
316
317    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
318        iomap!(
319            self.s
320                .write_char(b'"')
321                .and_then(|()| self.s.write_int(v))
322                .and_then(|()| self.s.write_char(b'"'))
323        )
324    }
325
326    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
327        iomap!(
328            self.s
329                .write_char(b'"')
330                .and_then(|()| self.s.write_int(v))
331                .and_then(|()| self.s.write_char(b'"'))
332        )
333    }
334
335    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
336        iomap!(
337            self.s
338                .write_char(b'"')
339                .and_then(|()| self.s.write_int(v))
340                .and_then(|()| self.s.write_char(b'"'))
341        )
342    }
343
344    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
345        iomap!(
346            self.s
347                .write_char(b'"')
348                .and_then(|()| self.s.write_int(v))
349                .and_then(|()| self.s.write_char(b'"'))
350        )
351    }
352
353    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
354        iomap!(
355            self.s
356                .write_char(b'"')
357                .and_then(|()| self.s.write_int(v))
358                .and_then(|()| self.s.write_char(b'"'))
359        )
360    }
361
362    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
363        iomap!(
364            self.s
365                .write_char(b'"')
366                .and_then(|()| self.s.write_int(v))
367                .and_then(|()| self.s.write_char(b'"'))
368        )
369    }
370
371    fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
372        Err(key_must_be_a_string())
373    }
374
375    fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
376        Err(key_must_be_a_string())
377    }
378
379    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
380        self.s.serialize_str(&v.to_string())
381    }
382
383    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
384        Err(key_must_be_a_string())
385    }
386
387    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
388        Err(key_must_be_a_string())
389    }
390
391    fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
392    where
393        T: ?Sized + serde_ext::Serialize,
394    {
395        Err(key_must_be_a_string())
396    }
397
398    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
399        Err(key_must_be_a_string())
400    }
401
402    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
403        Err(key_must_be_a_string())
404    }
405
406    fn serialize_newtype_variant<T>(
407        self,
408        _name: &'static str,
409        _variant_index: u32,
410        _variant: &'static str,
411        _value: &T,
412    ) -> Result<Self::Ok, Self::Error>
413    where
414        T: ?Sized + serde_ext::Serialize,
415    {
416        Err(key_must_be_a_string())
417    }
418
419    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
420        Err(key_must_be_a_string())
421    }
422
423    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
424        Err(key_must_be_a_string())
425    }
426
427    fn serialize_tuple_struct(
428        self,
429        _name: &'static str,
430        _len: usize,
431    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
432        Err(key_must_be_a_string())
433    }
434
435    fn serialize_tuple_variant(
436        self,
437        _name: &'static str,
438        _variant_index: u32,
439        _variant: &'static str,
440        _len: usize,
441    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
442        Err(key_must_be_a_string())
443    }
444
445    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
446        Err(key_must_be_a_string())
447    }
448
449    fn serialize_struct(
450        self,
451        _name: &'static str,
452        _len: usize,
453    ) -> Result<Self::SerializeStruct, Self::Error> {
454        Err(key_must_be_a_string())
455    }
456
457    fn serialize_struct_variant(
458        self,
459        _name: &'static str,
460        _variant_index: u32,
461        _variant: &'static str,
462        _len: usize,
463    ) -> Result<Self::SerializeStructVariant, Self::Error> {
464        Err(key_must_be_a_string())
465    }
466}
467
468impl<W> ser::SerializeStruct for SerializeMap<'_, W>
469where
470    W: Write,
471{
472    type Ok = ();
473    type Error = Error;
474    #[cfg_attr(not(feature = "no-inline"), inline)]
475    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
476    where
477        T: ?Sized + serde_ext::Serialize,
478    {
479        let SerializeMap {
480            ref mut s,
481            ref mut first,
482            ..
483        } = *self;
484        if *first {
485            *first = false;
486            iomap!(s.write_simple_string(key).and_then(|()| s.write(b":")))
487                .and_then(|()| value.serialize(&mut **s))
488        } else {
489            iomap!(
490                s.write(b",")
491                    .and_then(|()| s.write_simple_string(key))
492                    .and_then(|()| s.write(b":"))
493            )
494            .and_then(|()| value.serialize(&mut **s))
495        }
496    }
497    #[cfg_attr(not(feature = "no-inline"), inline)]
498    fn end(self) -> Result<Self::Ok, Self::Error> {
499        iomap!(self.s.write(b"}"))
500    }
501}
502
503struct SerializeStructVariant<'serializer, W: Write + 'serializer> {
504    s: &'serializer mut Serializer<W>,
505    first: bool,
506}
507
508impl<W> ser::SerializeStructVariant for SerializeStructVariant<'_, W>
509where
510    W: Write,
511{
512    type Ok = ();
513    type Error = Error;
514    #[cfg_attr(not(feature = "no-inline"), inline)]
515    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
516    where
517        T: ?Sized + serde_ext::Serialize,
518    {
519        let SerializeStructVariant {
520            ref mut s,
521            ref mut first,
522            ..
523        } = *self;
524        if *first {
525            *first = false;
526            iomap!(s.write_simple_string(key).and_then(|()| s.write(b":")))
527                .and_then(|()| value.serialize(&mut **s))
528        } else {
529            iomap!(
530                s.write(b",")
531                    .and_then(|()| s.write_simple_string(key))
532                    .and_then(|()| s.write(b":"))
533            )
534            .and_then(|()| value.serialize(&mut **s))
535        }
536    }
537    #[cfg_attr(not(feature = "no-inline"), inline)]
538    fn end(self) -> Result<Self::Ok, Self::Error> {
539        iomap!(self.s.write(b"}}"))
540    }
541}
542
543impl<'writer, W> ser::Serializer for &'writer mut Serializer<W>
544where
545    W: Write,
546{
547    type Ok = ();
548    type Error = Error;
549    type SerializeSeq = SerializeSeq<'writer, W>;
550    type SerializeTuple = SerializeSeq<'writer, W>;
551    type SerializeTupleStruct = SerializeSeq<'writer, W>;
552    type SerializeTupleVariant = SerializeSeq<'writer, W>;
553    type SerializeMap = SerializeMap<'writer, W>;
554    type SerializeStruct = SerializeMap<'writer, W>;
555    type SerializeStructVariant = SerializeStructVariant<'writer, W>;
556    #[cfg_attr(not(feature = "no-inline"), inline)]
557    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
558        if v {
559            iomap!(self.write(b"true"))
560        } else {
561            iomap!(self.write(b"false"))
562        }
563    }
564    #[cfg_attr(not(feature = "no-inline"), inline)]
565    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
566        iomap!(self.write_int(v))
567    }
568    #[cfg_attr(not(feature = "no-inline"), inline)]
569    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
570        iomap!(self.write_int(v))
571    }
572    #[cfg_attr(not(feature = "no-inline"), inline)]
573    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
574        iomap!(self.write_int(v))
575    }
576    #[cfg_attr(not(feature = "no-inline"), inline)]
577    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
578        iomap!(self.write_int(v))
579    }
580    #[cfg_attr(not(feature = "no-inline"), inline)]
581    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
582        iomap!(self.write_int(v))
583    }
584    #[cfg_attr(not(feature = "no-inline"), inline)]
585    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
586        iomap!(self.write_int(v))
587    }
588    #[cfg_attr(not(feature = "no-inline"), inline)]
589    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
590        iomap!(self.write_int(v))
591    }
592    #[cfg_attr(not(feature = "no-inline"), inline)]
593    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
594        iomap!(self.write_int(v))
595    }
596    #[cfg_attr(not(feature = "no-inline"), inline)]
597    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
598        iomap!(self.write_int(v))
599    }
600    #[cfg_attr(not(feature = "no-inline"), inline)]
601    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
602        iomap!(self.write_int(v))
603    }
604
605    #[cfg_attr(not(feature = "no-inline"), inline)]
606    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
607        iomap!(self.write_float(f64::from(v)))
608    }
609    #[cfg_attr(not(feature = "no-inline"), inline)]
610    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
611        iomap!(self.write_float(v))
612    }
613    #[cfg_attr(not(feature = "no-inline"), inline)]
614    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
615        // A char encoded as UTF-8 takes 4 bytes at most.
616        // taken from: https://docs.serde.rs/src/serde_json/ser.rs.html#213
617        let mut buf = [0; 4];
618        iomap!(self.write_simple_string(v.encode_utf8(&mut buf)))
619    }
620    #[cfg_attr(not(feature = "no-inline"), inline)]
621    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
622        iomap!(self.write_string(v))
623    }
624    #[cfg_attr(not(feature = "no-inline"), inline)]
625    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
626        iomap!(self.write(b"[").and_then(|()| {
627            if let Some((first, rest)) = v.split_first() {
628                self.write_int(*first).and_then(|()| {
629                    for v in rest {
630                        self.write(b",").and_then(|()| self.write_int(*v))?;
631                    }
632                    self.write(b"]")
633                })
634            } else {
635                self.write(b"]")
636            }
637        }))
638    }
639    #[cfg_attr(not(feature = "no-inline"), inline)]
640    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
641        self.serialize_unit()
642    }
643    #[cfg_attr(not(feature = "no-inline"), inline)]
644    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
645    where
646        T: ?Sized + serde_ext::Serialize,
647    {
648        value.serialize(self)
649    }
650    #[cfg_attr(not(feature = "no-inline"), inline)]
651    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
652        iomap!(self.write(b"null"))
653    }
654    #[cfg_attr(not(feature = "no-inline"), inline)]
655    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
656        self.serialize_unit()
657    }
658    #[cfg_attr(not(feature = "no-inline"), inline)]
659    fn serialize_unit_variant(
660        self,
661        _name: &'static str,
662        _variant_index: u32,
663        variant: &'static str,
664    ) -> Result<Self::Ok, Self::Error> {
665        iomap!(self.write_simple_string(variant))
666    }
667
668    #[cfg_attr(not(feature = "no-inline"), inline)]
669    fn serialize_newtype_struct<T>(
670        self,
671        _name: &'static str,
672        value: &T,
673    ) -> Result<Self::Ok, Self::Error>
674    where
675        T: ?Sized + serde_ext::Serialize,
676    {
677        value.serialize(self)
678    }
679
680    #[cfg_attr(not(feature = "no-inline"), inline)]
681    fn serialize_newtype_variant<T>(
682        self,
683        _name: &'static str,
684        _variant_index: u32,
685        variant: &'static str,
686        value: &T,
687    ) -> Result<Self::Ok, Self::Error>
688    where
689        T: ?Sized + serde_ext::Serialize,
690    {
691        iomap!(
692            self.write(b"{")
693                .and_then(|()| self.write_simple_string(variant))
694                .and_then(|()| self.write(b":"))
695        )
696        .and_then(|()| value.serialize(&mut *self))
697        .and_then(|()| iomap!(self.write(b"}")))
698    }
699    #[cfg_attr(not(feature = "no-inline"), inline)]
700    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
701        iomap!(self.write(b"[")).map(move |()| SerializeSeq {
702            s: self,
703            first: true,
704        })
705    }
706
707    #[cfg_attr(not(feature = "no-inline"), inline)]
708    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
709        self.serialize_seq(Some(len))
710    }
711
712    #[cfg_attr(not(feature = "no-inline"), inline)]
713    fn serialize_tuple_struct(
714        self,
715        _name: &'static str,
716        len: usize,
717    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
718        self.serialize_seq(Some(len))
719    }
720
721    #[cfg_attr(not(feature = "no-inline"), inline)]
722    fn serialize_tuple_variant(
723        self,
724        _name: &'static str,
725        _variant_index: u32,
726        variant: &'static str,
727        len: usize,
728    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
729        iomap!(
730            self.write(b"{")
731                .and_then(|()| self.write_simple_string(variant))
732                .and_then(|()| self.write(b":"))
733        )?;
734        self.serialize_seq(Some(len))
735    }
736
737    #[cfg_attr(not(feature = "no-inline"), inline)]
738    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
739        iomap!(self.write(b"{")).map(move |()| SerializeMap {
740            s: self,
741            first: true,
742        })
743    }
744
745    #[cfg_attr(not(feature = "no-inline"), inline)]
746    fn serialize_struct(
747        self,
748        _name: &'static str,
749        len: usize,
750    ) -> Result<Self::SerializeStruct, Self::Error> {
751        self.serialize_map(Some(len))
752    }
753
754    #[cfg_attr(not(feature = "no-inline"), inline)]
755    fn serialize_struct_variant(
756        self,
757        _name: &'static str,
758        _variant_index: u32,
759        variant: &'static str,
760        _len: usize,
761    ) -> Result<Self::SerializeStructVariant, Self::Error> {
762        iomap!(
763            self.write(b"{")
764                .and_then(|()| self.write_simple_string(variant))
765                .and_then(|()| self.write(b":{"))
766        )
767        .map(move |()| SerializeStructVariant {
768            s: self,
769            first: true,
770        })
771    }
772}
773
774#[cfg(test)]
775mod test {
776    #![allow(clippy::ignored_unit_patterns)]
777    #[cfg(not(target_arch = "wasm32"))]
778    use crate::{OwnedValue as Value, StaticNode};
779    #[cfg(not(target_arch = "wasm32"))]
780    use proptest::prelude::*;
781
782    #[test]
783    fn enum_tuple() {
784        #[derive(serde::Serialize, Clone)]
785        enum ErrType {
786            Instruction(i64, i64),
787        }
788
789        let err = ErrType::Instruction(2, 68800);
790
791        assert_eq!(
792            crate::to_string(&err).expect("failed to serialize"),
793            "{\"Instruction\":[2,68800]}",
794        );
795    }
796    #[test]
797    fn print_serde() {
798        #[derive(Clone, Debug, PartialEq, serde::Serialize)]
799        enum Segment {
800            Id { mid: usize },
801        }
802
803        assert_eq!(
804            "{\"Id\":{\"mid\":0}}",
805            crate::to_string(&Segment::Id { mid: 0 }).expect("to_string")
806        );
807    }
808
809    #[test]
810    fn numerical_map_serde() {
811        use std::collections::HashMap;
812
813        #[derive(Clone, Debug, PartialEq, serde::Serialize)]
814        struct Foo {
815            pub bar: HashMap<i32, i32>,
816        }
817
818        let mut foo = Foo {
819            bar: HashMap::new(),
820        };
821
822        foo.bar.insert(1337, 1337);
823
824        assert_eq!(
825            r#"{"bar":{"1337":1337}}"#,
826            crate::to_string(&foo).expect("to_string")
827        );
828    }
829
830    #[test]
831    fn empty_containers_of_unknown_length() {
832        use std::collections::BTreeMap;
833
834        // `collect_seq` over a filter passes `len: None`
835        struct Filtered(Vec<u8>);
836        impl serde::Serialize for Filtered {
837            fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
838                s.collect_seq(self.0.iter().filter(|x| **x > 10))
839            }
840        }
841        #[derive(serde::Serialize)]
842        struct Flat {
843            #[serde(flatten)]
844            rest: BTreeMap<String, u8>,
845        }
846
847        assert_eq!(
848            crate::to_string(&Filtered(vec![1, 2])).expect("to_string"),
849            "[]"
850        );
851        assert_eq!(
852            crate::to_string(&Flat {
853                rest: BTreeMap::new()
854            })
855            .expect("to_string"),
856            "{}"
857        );
858    }
859
860    #[cfg(not(feature = "128bit"))]
861    #[cfg(not(target_arch = "wasm32"))]
862    fn arb_json_value() -> BoxedStrategy<Value> {
863        let leaf = prop_oneof![
864            Just(Value::Static(StaticNode::Null)),
865            any::<bool>().prop_map(Value::from),
866            //(-1.0e306f64..1.0e306f64).prop_map(Value::from), // damn you float!
867            any::<i8>().prop_map(Value::from),
868            any::<i16>().prop_map(Value::from),
869            any::<i32>().prop_map(Value::from),
870            any::<i64>().prop_map(Value::from),
871            any::<u8>().prop_map(Value::from),
872            any::<u16>().prop_map(Value::from),
873            any::<u32>().prop_map(Value::from),
874            any::<u64>().prop_map(Value::from),
875            ".*".prop_map(Value::from),
876        ];
877        leaf.prop_recursive(
878            8,   // 8 levels deep
879            256, // Shoot for maximum size of 256 nodes
880            10,  // We put up to 10 items per collection
881            |inner| {
882                prop_oneof![
883                    // Take the inner strategy and make the two recursive cases.
884                    prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
885                    prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
886                ]
887            },
888        )
889        .boxed()
890    }
891
892    #[cfg(feature = "128bit")]
893    #[cfg(not(target_arch = "wasm32"))]
894    fn arb_json_value() -> BoxedStrategy<Value> {
895        let leaf = prop_oneof![
896            Just(Value::Static(StaticNode::Null)),
897            any::<bool>().prop_map(Value::from),
898            //(-1.0e306f64..1.0e306f64).prop_map(Value::from), // damn you float!
899            any::<i8>().prop_map(Value::from),
900            any::<i16>().prop_map(Value::from),
901            any::<i32>().prop_map(Value::from),
902            any::<i64>().prop_map(Value::from),
903            any::<i128>().prop_map(Value::from),
904            any::<u8>().prop_map(Value::from),
905            any::<u16>().prop_map(Value::from),
906            any::<u32>().prop_map(Value::from),
907            any::<u64>().prop_map(Value::from),
908            any::<u128>().prop_map(Value::from),
909            ".*".prop_map(Value::from),
910        ];
911        leaf.prop_recursive(
912            8,   // 8 levels deep
913            256, // Shoot for maximum size of 256 nodes
914            10,  // We put up to 10 items per collection
915            |inner| {
916                prop_oneof![
917                    // Take the inner strategy and make the two recursive cases.
918                    prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
919                    prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
920                ]
921            },
922        )
923        .boxed()
924    }
925
926    #[cfg(not(target_arch = "wasm32"))]
927    proptest! {
928        #![proptest_config(ProptestConfig {
929            // Setting both fork and timeout is redundant since timeout implies
930            // fork, but both are shown for clarity.
931            // Disabled for code coverage, enable to track bugs
932            // fork: true,
933            .. ProptestConfig::default()
934        })]
935
936        #[test]
937        fn prop_json_encode_decode(val in arb_json_value()) {
938            let mut encoded = crate::to_vec(&val).expect("to_vec");
939            println!("{}", String::from_utf8_lossy(&encoded.clone()));
940            let res: Value = crate::from_slice(encoded.as_mut_slice()).expect("can't convert");
941            assert_eq!(val, res);
942        }
943    }
944}