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