sonic_rs/lazyvalue/
ser.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use ::serde::ser::SerializeStruct;

use super::{owned::OwnedLazyValue, value::LazyValue};

impl<'a> serde::ser::Serialize for LazyValue<'a> {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let raw = self.as_raw_str();
        let mut s = serializer.serialize_struct(super::TOKEN, 1)?;
        // will directly write raw in `LazyValueStrEmitter::seriazlie_str`
        s.serialize_field(super::TOKEN, raw)?;
        s.end()
    }
}

impl serde::ser::Serialize for OwnedLazyValue {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let raw = self.as_raw_str();
        let mut s = serializer.serialize_struct(super::TOKEN, 1)?;
        // will directly write raw in `LazyValueStrEmitter::seriazlie_str`
        s.serialize_field(super::TOKEN, raw)?;
        s.end()
    }
}

#[cfg(test)]
mod test {
    use ::serde::{Deserialize, Serialize};

    use crate::{from_str, to_string, LazyValue, OwnedLazyValue, Result};

    #[test]
    fn test_lazyvalue_serde() {
        let json = r#"{
            "a": 1,
            "b": "2",
            "c": [3, 4, 5],
            "d": {
                "e": 6,
                "f": "7",
                "g": [8, 9, 10]
            }
        }"#;
        let value = crate::from_str::<crate::LazyValue>(json).unwrap();
        let json2 = crate::to_string(&value).unwrap();
        assert_eq!(json, json2);
    }

    #[derive(Debug, Deserialize, Serialize, PartialEq)]
    struct TestLazyValue<'a> {
        #[serde(borrow)]
        borrowed_lv: LazyValue<'a>,
        owned_lv: OwnedLazyValue,
    }

    #[test]
    fn test_raw_value_ok() {
        fn test_json_ok(json: &str) {
            let data = TestLazyValue {
                borrowed_lv: from_str(json).expect(json),
                owned_lv: from_str(json).expect(json),
            };

            // test long json for SIMD
            let json2 = json.to_string() + &" ".repeat(1000);
            let data2 = TestLazyValue {
                borrowed_lv: from_str(json).expect(&json2),
                owned_lv: from_str(json).expect(&json2),
            };
            assert_eq!(data, data2);
            let json = json.trim();
            let expect: String = format!("{{\"borrowed_lv\":{},\"owned_lv\":{}}}", json, json);
            let serialized = to_string(&data).expect(json);
            assert_eq!(expect, serialized);
            assert_eq!(from_str::<TestLazyValue>(&serialized).expect(json), data);
        }
        test_json_ok(r#""""#);
        test_json_ok(r#""raw value""#);
        test_json_ok(r#""哈哈哈☺""#);
        test_json_ok(r#"true"#);
        test_json_ok(r#"false"#);
        test_json_ok(r#"0"#);
        test_json_ok(r#"-1"#);
        test_json_ok(r#"-1e+1111111111111"#);
        test_json_ok(r#"-1e-1111111111111"#);
        test_json_ok(r#"{}"#);
        test_json_ok(r#"[]"#);
        test_json_ok(r#"{"":[], "": ["", "", []]}"#);
        test_json_ok(r#"{"":[], "": ["", "", []]}"#);
    }

    #[test]
    fn test_raw_value_failed() {
        fn test_json_failed(json: &str) {
            let ret: Result<LazyValue<'_>> = from_str(json);
            assert!(ret.is_err(), "invalid json is {}", json);
        }
        test_json_failed(r#"""#);
        test_json_failed(r#""raw " value""#);
        test_json_failed(r#"哈哈哈""#);
        test_json_failed(r#""\x""#);
        test_json_failed("\"\x00\"");
        test_json_failed(r#"tru"#);
        test_json_failed(r#"fals"#);
        test_json_failed(r#"0."#);
        test_json_failed(r#"-"#);
        test_json_failed(r#"-1e"#);
        test_json_failed(r#"-1e-"#);
        test_json_failed(r#"-1e-1.111"#);
        test_json_failed(r#"-1e-1,"#);
        test_json_failed(r#"{"#);
        test_json_failed(r#" ]"#);
        test_json_failed(r#"{"":[], ["", "", []]}"#);
    }
}