1// Copyright (c) 2023 Huawei Device Co., Ltd.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14use serde::Deserialize;
15use std::borrow::Cow;
16use ylong_json::from_str;
17
18#[derive(Deserialize, PartialEq, Debug)]
19struct ExampleOne {
20    #[serde(rename(deserialize = "Image"))]
21    image: InnerImage,
22}
23
24#[derive(Deserialize, PartialEq, Debug)]
25struct InnerImage {
26    #[serde(rename(deserialize = "Width"))]
27    width: u32,
28    #[serde(rename(deserialize = "Height"))]
29    height: u32,
30    #[serde(rename(deserialize = "Title"))]
31    title: String,
32    #[serde(rename(deserialize = "Thumbnail"))]
33    thumbnail: InnerThumbnail,
34    #[serde(rename(deserialize = "Animated"))]
35    animated: bool,
36    #[serde(rename(deserialize = "IDs"))]
37    ids: Vec<u32>,
38}
39
40#[derive(Deserialize, PartialEq, Debug)]
41struct InnerThumbnail {
42    #[serde(rename(deserialize = "Url"))]
43    url: String,
44    #[serde(rename(deserialize = "Height"))]
45    height: u32,
46    #[serde(rename(deserialize = "Width"))]
47    width: u32,
48}
49
50const RFC7159_EXAMPLE1: &str = r#"
51{
52    "Image": {
53        "Width":  800,
54        "Height": 600,
55        "Title":  "View from 15th Floor",
56        "Thumbnail": {
57            "Url":    "http://www.example.com/image/481989943",
58            "Height": 125,
59            "Width":  100
60        },
61        "Animated" : false,
62        "IDs": [116, 943, 234, 38793]
63    }
64}
65"#;
66
67#[test]
68fn sdv_adapt_serde_example_one() {
69    let de_res = from_str::<ExampleOne>(RFC7159_EXAMPLE1);
70    let expected = ExampleOne {
71        image: InnerImage {
72            width: 800,
73            height: 600,
74            thumbnail: InnerThumbnail {
75                url: String::from("http://www.example.com/image/481989943"),
76                height: 125,
77                width: 100,
78            },
79            animated: false,
80            ids: vec![116, 943, 234, 38793],
81            title: String::from("View from 15th Floor"),
82        },
83    };
84    assert_eq!(expected, de_res.unwrap());
85}
86
87const RFC7159_EXAMPLE2: &str = r#"
88[
89    {
90       "precision": "zip",
91       "Latitude":  37.7668,
92       "Longitude": -122.3959,
93       "Address":   "",
94       "City":      "SAN FRANCISCO",
95       "State":     "CA",
96       "Zip":       "94107",
97       "Country":   "US"
98    },
99    {
100       "precision": "zip",
101       "Latitude":  37.371991,
102       "Longitude": -122.026020,
103       "Address":   "",
104       "City":      "SUNNYVALE",
105       "State":     "CA",
106       "Zip":       "94085",
107       "Country":   "US"
108    }
109]
110"#;
111
112#[derive(Deserialize, PartialEq, Debug)]
113struct ExampleTwo<'a> {
114    precision: String,
115    #[serde(rename(deserialize = "Latitude"))]
116    latitude: f32,
117    #[serde(rename(deserialize = "Longitude"))]
118    longitude: f32,
119    #[serde(rename(deserialize = "Address"))]
120    address: String,
121    #[serde(rename(deserialize = "City"))]
122    city: String,
123    #[serde(rename(deserialize = "State"))]
124    state: String,
125    #[serde(rename(deserialize = "Zip"))]
126    zip: Cow<'a, str>,
127    #[serde(rename(deserialize = "Country"))]
128    country: Cow<'a, str>,
129}
130
131#[test]
132fn sdv_adapt_serde_example_two() {
133    let de_res = from_str::<Vec<ExampleTwo>>(RFC7159_EXAMPLE2).unwrap();
134    let expected_0 = ExampleTwo {
135        precision: String::from("zip"),
136        latitude: 37.7668,
137        longitude: -122.3959,
138        address: String::from(""),
139        city: String::from("SAN FRANCISCO"),
140        state: String::from("CA"),
141        zip: Cow::from("94107"),
142        country: Cow::from("US"),
143    };
144    let expected_1 = ExampleTwo {
145        precision: String::from("zip"),
146        latitude: 37.371_991,
147        longitude: -122.026_02,
148        address: String::from(""),
149        city: String::from("SUNNYVALE"),
150        state: String::from("CA"),
151        zip: Cow::from("94085"),
152        country: Cow::from("US"),
153    };
154    assert_eq!(expected_0, de_res[0]);
155    assert_eq!(expected_1, de_res[1]);
156}
157
158const JSON_PARSE_EXAMPLE3: &str = r#"
159{
160    "null_test" : {
161        "null1": null
162    },
163    "bool_test" : {
164        "boolean1": true,
165        "boolean2": false
166    },
167    "number_test" : {
168        "number1": 0,
169        "number2": -0,
170        "number3": 123,
171        "number4": -123,
172        "number5": 123.456,
173        "number6": -123.456,
174        "number7": 123.456e+7,
175        "number8": 123.456e-7,
176        "number9": 123.456E+7,
177        "number10": 123.456E-7,
178        "number11": -123.456e+7,
179        "number12": -123.456e-7,
180        "number13": -123.456E+7,
181        "number14": -123.456E-7,
182        "number15": 0.0,
183        "number16": -0.0e+7,
184        "number17": 3e2
185    },
186    "string_test" : {
187        "string1": "",
188        "string2": "Hello World",
189        "string3": "abcdefghijklmnopqrstuvwxyz",
190        "string4": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
191        "string5": "0123456789",
192        "string6": " \b\f\n\r\t",
193        "string7": "\"\\\/",
194        "string8": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
195        "string9": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A"
196    },
197    "array_test" : {
198        "array1": [  ],
199        "array2": [ true,  false
200                                     ],
201        "array3": [0 , 1 , -1 , 100 , -100],
202        "array4": [
203                0.0                    ,               -0.0,           1.0           ,
204        -1.0,                            12.34
205                             ,        -12.34   ],
206        "array5": [[[[[[["nest"]]]]]]]
207    },
208    "object_test" : {
209        "object1": null,
210        "object2":   null   ,
211        "object3": {"key1":"Null","key2": {"Bool":true},
212        "key3":{"Number":0.0},"key4":{"StringVal":"string"},
213        "key5":{"Array":[]},"key6":{"Object":null}},
214        "object4": {
215                "key1"                :                 "Null"   ,       "key2"
216                   :         {   "Bool"   :   true   }     ,            "key3"         :
217            {   "Number"   :   0.0   }      ,      "key4":{"StringVal":"string"}     ,
218                       "key5":                {"Array":[]},          "key6":        {
219                    "Object":null                  }
220        },
221        "object5": {"nest1": {"nest2": {"nest3": {"nest4": null}}}},
222        "": {
223            "": "key1",
224            "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" : "key2"
225        }
226    }
227}
228"#;
229
230#[derive(Deserialize, PartialEq, Debug)]
231struct ParseTest {
232    null_test: NullTest,
233    bool_test: BoolTest,
234    number_test: NumberTest,
235    string_test: StringTest,
236    array_test: ArrayTest,
237    object_test: ObjectTest,
238}
239
240#[derive(Deserialize, PartialEq, Debug)]
241struct StructNull;
242
243#[derive(Deserialize, PartialEq, Debug)]
244struct NullTest {
245    null1: StructNull,
246}
247
248#[derive(Deserialize, PartialEq, Debug)]
249struct BoolTest {
250    boolean1: bool,
251    boolean2: bool,
252}
253
254#[derive(Deserialize, PartialEq, Debug)]
255struct NumberTest {
256    number1: u8,
257    number2: i8,
258    number3: u16,
259    number4: i16,
260    number5: f32,
261    number6: f32,
262    number7: f64,
263    number8: f64,
264    number9: f64,
265    number10: f64,
266    number11: f64,
267    number12: f64,
268    number13: f64,
269    number14: f64,
270    number15: f64,
271    number16: f64,
272    number17: f64,
273}
274
275#[derive(Deserialize, PartialEq, Debug)]
276struct StringTest {
277    string1: String,
278    string2: String,
279    string3: String,
280    string4: String,
281    string5: String,
282    string6: String,
283    string7: String,
284    string8: String,
285    string9: String,
286}
287
288#[derive(Deserialize, PartialEq, Debug)]
289struct ArrayTest {
290    array1: Vec<StructNull>,
291    array2: Vec<bool>,
292    array3: Vec<i64>,
293    array4: Vec<f64>,
294    #[warn(clippy::type_complexity)]
295    array5: Vec<Vec<Vec<Vec<Vec<Vec<Vec<String>>>>>>>,
296}
297
298#[derive(Deserialize, PartialEq, Debug)]
299struct ObjectTest {
300    object1: StructNull,
301    object2: StructNull,
302    object3: ObjectThreeFour,
303    object4: ObjectThreeFour,
304    object5: ObjectFive,
305    #[serde(rename(deserialize = ""))]
306    object6: ObjectSix,
307}
308
309#[derive(Deserialize, PartialEq, Debug)]
310enum InnerValue {
311    Null,
312    Bool(bool),
313    Number(f64),
314    StringVal(String),
315    Array(Vec<InnerValue>),
316    Object(StructNull),
317}
318
319#[derive(Deserialize, PartialEq, Debug)]
320struct ObjectThreeFour {
321    key1: InnerValue,
322    key2: InnerValue,
323    key3: InnerValue,
324    key4: InnerValue,
325    key5: InnerValue,
326    key6: InnerValue,
327}
328
329#[derive(Deserialize, PartialEq, Debug)]
330struct ObjectFive {
331    nest1: NestOne,
332}
333
334#[derive(Deserialize, PartialEq, Debug)]
335struct NestOne {
336    nest2: NestTwo,
337}
338
339#[derive(Deserialize, PartialEq, Debug)]
340struct NestTwo {
341    nest3: NestThree,
342}
343
344#[derive(Deserialize, PartialEq, Debug)]
345struct NestThree {
346    nest4: NestFour,
347}
348
349#[derive(Deserialize, PartialEq, Debug)]
350struct NestFour;
351
352#[derive(Deserialize, PartialEq, Debug)]
353struct ObjectSix {
354    #[serde(rename(deserialize = ""))]
355    mem1: String,
356    #[serde(rename(
357        deserialize = "/\\\"\u{CAFE}\u{BABE}\u{AB98}\u{FCDE}\u{bcda}\u{ef4A}\u{0008}\u{000c}\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
358    ))]
359    mem2: String,
360}
361
362#[test]
363fn sdv_adapt_serde_example_three() {
364    let de_res = from_str::<ParseTest>(JSON_PARSE_EXAMPLE3);
365    let expected = ParseTest {
366        null_test: NullTest { null1: StructNull },
367        bool_test: BoolTest {
368            boolean1: true,
369            boolean2: false,
370        },
371        number_test: NumberTest {
372            number1: 0,
373            number2: 0,
374            number3: 123,
375            number4: -123,
376            number5: 123.456,
377            number6: -123.456,
378            number7: 1234560000.0,
379            number8: 1.23456e-5,
380            number9: 1234560000.0,
381            number10: 1.23456e-5,
382            number11: -1234560000.0,
383            number12: -1.23456e-5,
384            number13: -1234560000.0,
385            number14: -1.23456e-5,
386            number15: 0.0,
387            number16: -0.0,
388            number17: 300.0,
389        },
390        string_test: StringTest {
391            string1: String::from(""),
392            string2: String::from("Hello World"),
393            string3: String::from("abcdefghijklmnopqrstuvwxyz"),
394            string4: String::from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
395
396            string5: String::from("0123456789"),
397            string6: String::from(" \u{8}\u{c}\n\r\t"),
398            string7: String::from("\"\\/"),
399            string8: String::from("`1~!@#$%^&*()_+-={':[,]}|;.</>?"),
400            string9: String::from("ģ䕧覫췯ꯍ\u{ef4a}"),
401        },
402        array_test: ArrayTest {
403            array1: vec![],
404            array2: vec![true, false],
405            array3: vec![0, 1, -1, 100, -100],
406            array4: vec![0.0, -0.0, 1.0, -1.0, 12.34, -12.34],
407            array5: vec![vec![vec![vec![vec![vec![vec![String::from("nest")]]]]]]],
408        },
409        object_test: ObjectTest {
410            object1: StructNull,
411            object2: StructNull,
412            object3: ObjectThreeFour {
413                key1: InnerValue::Null,
414                key2: InnerValue::Bool(true),
415                key3: InnerValue::Number(0.0),
416                key4: InnerValue::StringVal(String::from("string")),
417                key5: InnerValue::Array(vec![]),
418                key6: InnerValue::Object(StructNull),
419            },
420            object4: ObjectThreeFour {
421                key1: InnerValue::Null,
422                key2: InnerValue::Bool(true),
423                key3: InnerValue::Number(0.0),
424                key4: InnerValue::StringVal(String::from("string")),
425                key5: InnerValue::Array(vec![]),
426                key6: InnerValue::Object(StructNull),
427            },
428            object5: ObjectFive {
429                nest1: NestOne {
430                    nest2: NestTwo {
431                        nest3: NestThree { nest4: NestFour },
432                    },
433                },
434            },
435            object6: ObjectSix {
436                mem1: String::from("key1"),
437                mem2: String::from("key2"),
438            },
439        },
440    };
441    assert_eq!(expected, de_res.unwrap());
442}
443