sonic_rs/serde/
mod.rs

1//! Serde between JSON text and Rust data structure.
2
3pub(crate) mod de;
4pub(crate) mod number;
5pub(crate) mod rawnumber;
6pub(crate) mod ser;
7
8pub(crate) use self::de::tri;
9pub use self::{
10    de::{
11        from_reader, from_slice, from_slice_unchecked, from_str, Deserializer, StreamDeserializer,
12    },
13    number::{JsonNumberTrait, Number},
14    rawnumber::RawNumber,
15    ser::{
16        to_lazyvalue, to_string, to_string_pretty, to_vec, to_vec_pretty, to_writer,
17        to_writer_pretty, Serializer,
18    },
19};
20
21#[cfg(test)]
22#[allow(clippy::mutable_key_type)]
23mod test {
24    use std::{
25        borrow::Cow,
26        collections::{BTreeMap, HashMap},
27        hash::Hash,
28        marker::PhantomData,
29    };
30
31    use bytes::Bytes;
32    use faststr::FastStr;
33    use serde::{de::IgnoredAny, ser::SerializeMap, Deserialize, Serialize};
34
35    use super::*;
36    use crate::{Result, Value};
37
38    macro_rules! hashmap {
39        () => {
40            HashMap::new()
41        };
42        ($($k:expr => $v:expr),+ $(,)?) => {
43            {
44                let mut m = HashMap::new();
45                $(
46                    m.insert($k, $v);
47                )+
48                m
49            }
50        };
51    }
52
53    struct UnorderedMap<'a> {
54        entries: &'a [(&'a str, u8)],
55    }
56
57    impl Serialize for UnorderedMap<'_> {
58        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
59        where
60            S: serde::Serializer,
61        {
62            let mut map = serializer.serialize_map(Some(self.entries.len()))?;
63            for (key, value) in self.entries {
64                map.serialize_entry(key, value)?;
65            }
66            map.end()
67        }
68    }
69
70    #[test]
71    fn test_serializer_sort_map_keys_toggle() {
72        let entries = [("b", 1u8), ("a", 2u8), ("c", 3u8)];
73        let unordered = UnorderedMap { entries: &entries };
74
75        let mut ser = Serializer::new(Vec::new());
76        unordered.serialize(&mut ser).unwrap();
77        let output = String::from_utf8(ser.into_inner()).unwrap();
78        let expected_default = r#"{"b":1,"a":2,"c":3}"#;
79        assert_eq!(output, expected_default);
80
81        let mut ser = Serializer::new(Vec::new()).sort_map_keys();
82        unordered.serialize(&mut ser).unwrap();
83        let output = String::from_utf8(ser.into_inner()).unwrap();
84        assert_eq!(output, r#"{"a":2,"b":1,"c":3}"#);
85    }
86
87    #[test]
88    fn test_value_to_string_sort_behavior() {
89        let value: Value = crate::json!({"b": 1, "a": 2, "c": 3});
90
91        let json = to_string(&value).unwrap();
92        let expected_sorted = r#"{"a":2,"b":1,"c":3}"#;
93
94        if cfg!(feature = "sort_keys") {
95            assert_eq!(json, expected_sorted);
96        } else {
97            let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
98            assert_eq!(parsed, serde_json::json!({"b": 1, "a": 2, "c": 3}));
99        }
100
101        let mut ser = Serializer::new(Vec::new()).sort_map_keys();
102        value.serialize(&mut ser).unwrap();
103        let sorted_json = String::from_utf8(ser.into_inner()).unwrap();
104        assert_eq!(sorted_json, expected_sorted);
105    }
106
107    #[test]
108    fn test_value_serializer_sort_map_keys() {
109        let value: Value = crate::json!({"delta": 4, "beta": 2, "alpha": 1});
110
111        let mut ser = Serializer::new(Vec::new());
112        value.serialize(&mut ser).unwrap();
113        let default_json = String::from_utf8(ser.into_inner()).unwrap();
114
115        if cfg!(feature = "sort_keys") {
116            assert_eq!(default_json, r#"{"alpha":1,"beta":2,"delta":4}"#);
117        } else {
118            let parsed: serde_json::Value = serde_json::from_str(&default_json).unwrap();
119            assert_eq!(
120                parsed,
121                serde_json::json!({"delta": 4, "beta": 2, "alpha": 1})
122            );
123        }
124
125        let mut ser = Serializer::new(Vec::new()).sort_map_keys();
126        value.serialize(&mut ser).unwrap();
127        let sorted = String::from_utf8(ser.into_inner()).unwrap();
128        assert_eq!(sorted, r#"{"alpha":1,"beta":2,"delta":4}"#);
129    }
130
131    #[derive(Debug, Deserialize, Serialize, PartialEq)]
132    struct Foo {
133        name: FastStr,
134        id: u64,
135    }
136
137    #[derive(Debug, Deserialize, Serialize, Hash, Eq, PartialEq)]
138    enum Enum {
139        Zero = 0,
140        One = 1,
141        Two = 2,
142    }
143
144    #[derive(Debug, Deserialize, Serialize, PartialEq)]
145    enum FieldEnum {
146        Integer(i8),
147        Tuple((FastStr, i32)),
148        Struct(Foo),
149        Unit,
150    }
151
152    #[derive(Debug, Deserialize, Serialize, PartialEq)]
153    enum FieldlessEnum {
154        Tuple(),
155        Struct {},
156        Unit,
157    }
158
159    // newtype struct
160    #[derive(Debug, Deserialize, Serialize, PartialEq)]
161    struct NewtypeStruct<'a>(&'a str);
162
163    // A unit struct
164    #[derive(Debug, Deserialize, Serialize, PartialEq)]
165    struct Unit;
166
167    // A uint struct
168    #[derive(Debug, Deserialize, Serialize, PartialEq)]
169    struct Phan<T> {
170        phan: String,
171        _data: PhantomData<T>,
172    }
173
174    // A tuple struct
175    #[derive(Debug, Deserialize, Serialize, PartialEq)]
176    struct Pair(i32, f32);
177
178    #[derive(Debug, Deserialize, Serialize, PartialEq)]
179    struct TestData<'a> {
180        fieldless: FieldlessEnum,
181        enummap: HashMap<Enum, FieldlessEnum>,
182        nummap: HashMap<i64, FieldlessEnum>,
183        enum_: Enum,
184
185        // basic types
186        boolean: bool,
187        integer: i32,
188        float: f64,
189        int128: i128,
190        uint128: u128,
191        char_: char,
192        // string or bytes
193        str_: &'a str,
194        // bytes_: &'a [u8],
195        string: String,
196        faststr: FastStr,
197        #[serde(borrow)]
198        cow: Cow<'a, str>,
199        // containers
200        vector: Vec<u32>,
201        array: [u32; 1],
202        empty_array: [u8; 0],
203        map: HashMap<FastStr, f64>,
204        map_opkey: HashMap<Option<FastStr>, f64>,
205
206        // enum types
207        option: Option<String>,
208        fieldenum: FieldEnum,
209
210        // tuple or struct
211        tuple: (u64, String),
212        tuple_struct: Pair,
213        unit_struct: Unit,
214
215        #[serde(borrow)]
216        wrapper: NewtypeStruct<'a>,
217        phan_struct: Phan<&'a ()>,
218
219        // non-str keys for map
220        map_u8: HashMap<u8, u8>,
221        map_u16: HashMap<u16, u16>,
222        map_u32: HashMap<u32, u32>,
223        map_u64: HashMap<u64, u64>,
224        map_u128: HashMap<u128, u128>,
225
226        map_i8: HashMap<i8, i8>,
227        map_i16: HashMap<i16, i16>,
228        map_i32: HashMap<i32, i32>,
229        map_i64: HashMap<i64, i64>,
230        map_i128: HashMap<i128, i128>,
231
232        map_bool: HashMap<bool, bool>,
233
234        #[serde(skip_serializing)]
235        ignored: IgnoredAny,
236    }
237
238    fn gen_data() -> TestData<'static> {
239        TestData {
240            boolean: true,
241            integer: -42,
242            float: 3.33,
243            int128: -22_000_000_000_000_000_000_000_000,
244            uint128: 11_000_000_000_000_000_000_000_000,
245            char_: 'A',
246            str_: "hello world",
247            // bytes_: &[0x52, 0x75, 0x73, 0x74],
248            string: String::from("hello world"),
249            faststr: FastStr::from("hello world"),
250            cow: Cow::Borrowed("borrowed"),
251            vector: vec![42, 24, 7],
252            array: [99],
253            empty_array: [],
254            map: hashmap!(
255                FastStr::from("key1") => 1.1,
256                FastStr::from("key2") => 2.2,
257            ),
258            map_opkey: hashmap!(
259                Some(FastStr::from("key1")) => 1.1,
260            ),
261            option: Some(String::from("I'm here")),
262            enummap: hashmap!(
263                Enum::Zero => FieldlessEnum::Struct {},
264                Enum::One => FieldlessEnum::Unit,
265            ),
266            nummap: hashmap!(
267                0 => FieldlessEnum::Struct {},
268                1 => FieldlessEnum::Unit,
269            ),
270            fieldenum: FieldEnum::Tuple((FastStr::from("test"), 42)),
271            fieldless: FieldlessEnum::Struct {},
272            enum_: Enum::One,
273
274            tuple: (42, String::from("test")),
275            tuple_struct: Pair(42, 3.33),
276            unit_struct: Unit,
277            wrapper: NewtypeStruct("hello"),
278            phan_struct: Phan {
279                phan: String::from("test data"),
280                _data: PhantomData,
281            },
282
283            map_u8: hashmap!(u8::MAX => u8::MAX),
284            map_u16: hashmap!(u16::MAX => u16::MAX),
285            map_u32: hashmap!(u32::MAX => u32::MAX),
286            map_u64: hashmap!(u64::MAX => u64::MAX),
287            map_u128: hashmap!(u128::MAX => u128::MAX),
288
289            map_i8: hashmap!(i8::MAX => i8::MAX),
290            map_i16: hashmap!(i16::MAX => i16::MAX),
291            map_i32: hashmap!(i32::MAX => i32::MAX),
292            map_i64: hashmap!(i64::MAX => i64::MAX),
293            map_i128: hashmap!(i128::MAX => i128::MAX),
294
295            map_bool: hashmap!(true => true, false => false),
296            ignored: IgnoredAny,
297        }
298    }
299
300    #[allow(clippy::mutable_key_type)]
301    #[test]
302    fn test_serde_struct() {
303        let data = gen_data();
304        let expect = serde_json::to_string(&data).expect("Failed to serialize the data");
305        let got = to_string(&data).expect("Failed to serialize the data");
306        assert_eq!(expect, got);
307        println!("serialized json is {got}");
308
309        let got = r#"{"ignored":0,"#.to_string() + &got[1..];
310        let expect_value: TestData =
311            serde_json::from_str(&got).expect("Failed to deserialize the data");
312        let got_value: TestData = from_str(&got).expect("Failed to deserialize the data");
313        assert_eq!(expect_value, got_value);
314    }
315
316    #[test]
317    fn test_struct_with_skipped() {
318        let data = gen_data();
319        let json = r#"{"ignored":0, "unknown":0,"unknown":null,"unknown":1234e123,"unknown":1.234,"unknown":[],"unknown":{},"unknown":{"a":[]},"unknown":[1,2,3],"#.to_string()
320            + &serde_json::to_string(&data).expect("Failed to serialize the data")[1..];
321
322        let expect: TestData = serde_json::from_str(&json).unwrap();
323        let val: TestData = from_str(&json).unwrap();
324        assert_eq!(val, expect);
325    }
326
327    #[test]
328    fn test_struct_with_ignored() {
329        let data = gen_data();
330        let json = r#"{"ignored":[1,2,3],"#.to_string()
331            + &serde_json::to_string(&data).expect("Failed to serialize the data")[1..];
332
333        let expect: TestData = serde_json::from_str(&json).unwrap();
334        let val: TestData = from_str(&json).unwrap();
335        assert_eq!(val, expect);
336    }
337
338    #[test]
339    fn test_serde_time() {
340        use chrono::{DateTime, Utc};
341
342        let time: DateTime<Utc> = Utc::now();
343        let out = to_string_pretty(&time).unwrap();
344        let got = from_str::<DateTime<Utc>>(&out).unwrap();
345        assert_eq!(time, got);
346    }
347
348    fn read_file(path: &str, vec: &mut Vec<u8>) {
349        use std::io::Read;
350        let root = env!("CARGO_MANIFEST_DIR").to_owned();
351        std::fs::File::open(root + "/benchmarks/benches/testdata/" + path)
352            .unwrap()
353            .read_to_end(vec)
354            .unwrap();
355    }
356
357    #[test]
358    #[cfg(not(target_arch = "wasm32"))]
359    fn test_struct() {
360        use schema::{citm_catalog::CitmCatalog, twitter::Twitter};
361        let mut vec = Vec::new();
362        read_file("twitter.json", &mut vec);
363        let _value: Twitter = from_slice(&vec).unwrap();
364
365        let mut vec = Vec::new();
366        read_file("citm_catalog.json", &mut vec);
367        let _value: CitmCatalog = from_slice(&vec).unwrap();
368    }
369
370    #[derive(Debug, Deserialize, Serialize, PartialEq)]
371    struct TestJsonNumber {
372        num: Number,
373        raw_num: RawNumber,
374    }
375
376    #[test]
377    fn test_json_number() {
378        let number: RawNumber = from_str("  123").unwrap();
379        assert_eq!(number, RawNumber::new("123"));
380        assert_eq!(to_string(&number).unwrap(), "123");
381
382        let number: RawNumber = from_str(r#""0.123""#).unwrap();
383        assert_eq!(number, RawNumber::new("0.123"));
384        assert_eq!(to_string(&number).unwrap(), "0.123");
385        assert!(number.is_f64());
386        assert_eq!(number.as_f64().unwrap(), 0.123);
387        assert_eq!(number.as_u64(), None);
388
389        let num: Number = number.try_into().unwrap();
390        assert_eq!(num.as_f64().unwrap(), 0.123);
391        assert_eq!(num.as_u64(), None);
392
393        let data = TestJsonNumber {
394            num: Number::from_f64(1.23).unwrap(),
395            raw_num: RawNumber::new("1.23e123"),
396        };
397        let expect = r#"{"num":1.23,"raw_num":1.23e123}"#;
398        let got = to_string(&data).expect("Failed to serialize the data");
399        assert_eq!(expect, got);
400        println!("serialized json is {got}");
401
402        let got_value: TestJsonNumber = from_str(expect).expect("Failed to deserialize the data");
403        assert_eq!(data, got_value);
404    }
405
406    #[test]
407    fn test_json_number_invalid() {
408        fn test_json_failed(json: &str) {
409            let ret: Result<RawNumber> = from_str(json);
410            assert!(ret.is_err(), "invalid json is {json}");
411        }
412        test_json_failed(r#"0."#);
413        test_json_failed(r#"-"#);
414        test_json_failed(r#"-1e"#);
415        test_json_failed(r#"-1e-"#);
416        test_json_failed(r#"-1e-1.111"#);
417        test_json_failed(r#"-1e-1,"#);
418        test_json_failed(
419            r#""0.123#);
420        test_json_failed(r#""-""#,
421        );
422        test_json_failed(r#""-1e""#);
423    }
424
425    #[cfg(not(feature = "utf8_lossy"))]
426    #[test]
427    fn test_invalid_utf8() {
428        let data = [b'"', 0, 0, 0, 0x80, 0x90, b'"'];
429        let value: crate::Result<String> = from_slice(&data);
430        assert_eq!(
431            value.err().unwrap().to_string(),
432            "Invalid UTF-8 characters in json at line 1 column 5\n\n\t\"\0\0\0��\"\n\t....^..\n"
433        );
434
435        // char's deserialize will iterator on the `str`
436        let data = [34, 255, 34];
437        let value: crate::Result<char> = from_slice(&data);
438        assert_eq!(
439            value.err().unwrap().to_string(),
440            "Invalid UTF-8 characters in json at line 1 column 2\n\n\t\"�\"\n\t.^.\n"
441        );
442    }
443
444    macro_rules! test_from_slice {
445        ($ty:ty, $data:expr) => {
446            test_from! {$ty, from_slice, $data};
447        };
448    }
449
450    macro_rules! test_from {
451        ($ty:ty, $f:ty, $data:expr) => {
452            ::paste::paste! {
453            match serde_json::$f::<$ty>($data) {
454                Ok(jv) => {
455                    let sv = crate::$f::<$ty>($data).expect(&format!(
456                        "parse valid json {:?} failed for type {}",
457                        $data,
458                        stringify!($ty)
459                    ));
460                    assert_eq!(sv, jv);
461
462                    // fuzz the struct to_string
463                    let sout = crate::to_string(&sv).unwrap();
464                    let jout = serde_json::to_string(&jv).unwrap();
465                    let sv = crate::from_str::<$ty>(&sout).unwrap();
466                    let jv = serde_json::from_str::<$ty>(&jout).unwrap();
467                    assert_eq!(sv, jv);
468                }
469                Err(err) => {
470                    let _ = crate::$f::<$ty>($data).expect_err(&format!(
471                        "parse invalid json {:?} wrong for type {}, should error: {}",
472                        $data,
473                        stringify!($ty),
474                        err
475                    ));
476                }
477            }
478            }
479        };
480    }
481
482    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
483    pub struct Data {
484        #[serde(with = "serde_bytes")]
485        pub content: Vec<u8>,
486    }
487
488    use serde_bytes::ByteBuf;
489
490    // the testcase is found by fuzzing tests
491    #[test]
492    fn test_more_structs() {
493        // invalid json: has control chars
494        test_from_slice!(String, &[34, 58, 55, 10, 0, 34, 32, 10]);
495        test_from_slice!(String, &[34, b'\\', b't', 9, 34]);
496        test_from_slice!(String, &[34, 92, 34, 34]);
497        test_from_slice!(String, b"\"\\umap9map009\"");
498        test_from_slice!(Foo, &b"[\"5XXXXXXZX:XXZX:[\",-0]"[..]);
499        test_from_slice!(Bytes, &b"\"hello world\""[..]);
500        test_from_slice!(
501            Bytes,
502            &b"[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]"[..]
503        );
504        test_from_slice!(
505            ByteBuf,
506            &b"[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]"[..]
507        );
508        test_from_slice!(ByteBuf, &b"\"hello world\""[..]);
509        test_from_slice!(Bytes, &b"[]"[..]);
510        test_from_slice!(Data, &br#"{"content":[1,2,3,4,5]}"#[..]);
511    }
512
513    #[test]
514    fn test_serde_invalid_utf8() {
515        let json = r#""王先生""#;
516
517        let (encoded, _, error) = encoding_rs::GB18030.encode(json);
518        assert!(!error, "Encoded error");
519
520        let obj: &[u8] = from_slice(encoded.as_ref()).expect("Failed deserialize");
521        println!("Deserialized {obj:?}");
522
523        let sout = crate::to_string(&obj).unwrap();
524        let jout = serde_json::to_string(&obj).unwrap();
525        assert_eq!(jout, sout);
526        println!("json is {jout}");
527        // this will failed
528        // let jv = serde_json::from_str::<&[u8]>(&jout).unwrap();
529    }
530
531    #[test]
532    fn test_ser_errors() {
533        #[derive(Debug, serde::Serialize, Hash, Default, Eq, PartialEq)]
534        struct User {
535            string: String,
536            number: i32,
537            array: Vec<String>,
538        }
539
540        let mut map = HashMap::<User, i64>::new();
541        map.insert(User::default(), 123);
542
543        let got = to_string(&map);
544        println!("{got:?}");
545        assert!(got.is_err());
546    }
547
548    #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone)]
549    struct Float;
550    impl Serialize for Float {
551        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
552        where
553            S: serde::Serializer,
554        {
555            serializer.serialize_f32(1.23)
556        }
557    }
558    impl<'de> Deserialize<'de> for Float {
559        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
560        where
561            D: serde::Deserializer<'de>,
562        {
563            f32::deserialize(deserializer).map(|_| Float)
564        }
565    }
566
567    #[test]
568    fn test_float_key() {
569        // map with float key
570        let mut map = BTreeMap::new();
571        map.insert(&Float, "x");
572
573        test_from!(BTreeMap<Float, String>, from_str, "{\"1.23\":\"x\"}" );
574        test_from!(BTreeMap<Float, String>, from_str, "{\"1.23\":null}" );
575    }
576
577    // test deserialize into different mapkeys
578    #[derive(PartialEq, Debug)]
579    struct MapKeys<'a> {
580        invalutf: Vec<u8>,
581        bytes: Vec<u8>,
582        string: String,
583        bool: bool,
584
585        i8: i8,
586        i16: i16,
587        i32: i32,
588        i64: i64,
589        i128: i128,
590
591        u8: u8,
592        u16: u16,
593        u32: u32,
594        u64: u64,
595        u128: u128,
596
597        isize: isize,
598        usize: usize,
599
600        f32: f32,
601        f64: f64,
602        option: Option<i64>,
603        wrapper: NewtypeStruct<'a>,
604        enum_key: Enum,
605        char_key: char,
606        ignored: IgnoredAny,
607    }
608
609    fn gen_keys_json() -> String {
610        r#"
611        {   "invalid utf8 here": "invalid utf8 here",
612            "bytes": [1,2,3],
613            "string": "hello",
614
615            "true": true,
616
617            "1": 1,
618            "123": 123,
619            "-123": -123,
620            "12345": 12345,
621            "1": 1,
622
623            "1": 1,
624            "123": 123,
625            "123": -123,
626            "12345": 12345,
627            "1": 1,
628
629            "12345": 12345,
630            "1": 1,
631
632            "1.23e+2": 1.23,
633            "-1.23": -1.23,
634
635            "123": "option",
636
637            "wrapper": {},
638
639            "Zero": "enum",
640
641            "A": "char",
642
643            "ignored": "ignored"
644        }
645        "#
646        .to_string()
647        .replace("invalid utf8", unsafe {
648            std::str::from_utf8_unchecked(&[0xff, 0xff, 0xff][..])
649        })
650    }
651
652    impl<'de> serde::de::Deserialize<'de> for MapKeys<'de> {
653        fn deserialize<D>(d: D) -> std::result::Result<Self, D::Error>
654        where
655            D: serde::Deserializer<'de>,
656        {
657            struct Visitor {}
658
659            impl<'de> serde::de::Visitor<'de> for Visitor {
660                type Value = MapKeys<'de>;
661
662                fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
663                    f.write_str("a map")
664                }
665
666                fn visit_map<A>(self, mut map: A) -> std::result::Result<Self::Value, A::Error>
667                where
668                    A: serde::de::MapAccess<'de>,
669                {
670                    fn parse_key<'de, V, A>(map: &mut A) -> std::result::Result<V, A::Error>
671                    where
672                        A: serde::de::MapAccess<'de>,
673                        V: serde::Deserialize<'de>,
674                    {
675                        let key = map.next_key::<V>()?.unwrap();
676                        let _ = map.next_value::<IgnoredAny>()?;
677                        Ok(key)
678                    }
679
680                    Ok(MapKeys {
681                        invalutf: parse_key::<&'de [u8], A>(&mut map)?.to_owned(),
682                        bytes: parse_key::<&'de [u8], A>(&mut map)?.to_owned(),
683                        string: parse_key::<String, A>(&mut map)?,
684                        bool: parse_key::<bool, A>(&mut map)?,
685                        i8: parse_key::<i8, A>(&mut map)?,
686                        i16: parse_key::<i16, A>(&mut map)?,
687                        i32: parse_key::<i32, A>(&mut map)?,
688                        i64: parse_key::<i64, A>(&mut map)?,
689                        i128: parse_key::<i128, A>(&mut map)?,
690                        u8: parse_key::<u8, A>(&mut map)?,
691                        u16: parse_key::<u16, A>(&mut map)?,
692                        u32: parse_key::<u32, A>(&mut map)?,
693                        u64: parse_key::<u64, A>(&mut map)?,
694                        u128: parse_key::<u128, A>(&mut map)?,
695                        isize: parse_key::<isize, A>(&mut map)?,
696                        usize: parse_key::<usize, A>(&mut map)?,
697                        f32: parse_key::<f32, A>(&mut map)?,
698                        f64: parse_key::<f64, A>(&mut map)?,
699                        option: parse_key::<Option<i64>, A>(&mut map)?,
700                        wrapper: parse_key::<NewtypeStruct<'de>, A>(&mut map)?,
701                        enum_key: parse_key::<Enum, A>(&mut map)?,
702                        char_key: parse_key::<char, A>(&mut map)?,
703                        ignored: parse_key::<IgnoredAny, A>(&mut map)?,
704                    })
705                }
706            }
707            d.deserialize_map(Visitor {})
708        }
709    }
710
711    #[test]
712    fn test_parse_map_keys() {
713        let s = gen_keys_json();
714        let expect: MapKeys = serde_json::from_str(&s).unwrap();
715        let got: MapKeys = crate::from_str(&s).unwrap();
716        assert_eq!(expect, got);
717    }
718
719    #[test]
720    fn test_utf8_lossy() {
721        let data = [&[b'\"', 0xff, b'\"'][..], br#""\uD800""#, br#""\udc00""#];
722
723        for d in data {
724            let mut de = Deserializer::from_slice(d).utf8_lossy();
725            let value: String = de.deserialize().unwrap();
726            assert_eq!(value, "�");
727        }
728
729        for d in data {
730            let mut de = Deserializer::from_slice(d).utf8_lossy();
731            let value: Value = de.deserialize().unwrap();
732            assert_eq!(value, "�");
733        }
734
735        for d in data {
736            let mut de = Deserializer::from_slice(d);
737            let err: crate::Error = de.deserialize::<String>().expect_err("should error");
738            eprintln!("{err}");
739            assert!(err.is_syntax());
740        }
741    }
742
743    #[test]
744    fn test_serialize_float_non_trailing_zero() {
745        use serde::Serialize;
746
747        #[derive(Serialize)]
748        struct FloatTest {
749            value: f64,
750        }
751
752        let test = FloatTest { value: 18.0 };
753        let json = to_string(&test).unwrap();
754
755        #[cfg(feature = "non_trailing_zero")]
756        assert_eq!(json, r#"{"value":18}"#);
757
758        #[cfg(not(feature = "non_trailing_zero"))]
759        assert_eq!(json, r#"{"value":18.0}"#);
760
761        let test = FloatTest { value: 18.1 };
762        let json = to_string(&test).unwrap();
763        assert_eq!(json, r#"{"value":18.1}"#);
764    }
765}