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 
14 use serde::Deserialize;
15 use std::borrow::Cow;
16 use ylong_json::from_str;
17 
18 #[derive(Deserialize, PartialEq, Debug)]
19 struct ExampleOne {
20     #[serde(rename(deserialize = "Image"))]
21     image: InnerImage,
22 }
23 
24 #[derive(Deserialize, PartialEq, Debug)]
25 struct 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)]
41 struct 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 
50 const 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]
sdv_adapt_serde_example_one()68 fn 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 
87 const 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)]
113 struct 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]
sdv_adapt_serde_example_two()132 fn 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 
158 const 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)]
231 struct 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)]
241 struct StructNull;
242 
243 #[derive(Deserialize, PartialEq, Debug)]
244 struct NullTest {
245     null1: StructNull,
246 }
247 
248 #[derive(Deserialize, PartialEq, Debug)]
249 struct BoolTest {
250     boolean1: bool,
251     boolean2: bool,
252 }
253 
254 #[derive(Deserialize, PartialEq, Debug)]
255 struct 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)]
276 struct 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)]
289 struct 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)]
299 struct 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)]
310 enum 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)]
320 struct 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)]
330 struct ObjectFive {
331     nest1: NestOne,
332 }
333 
334 #[derive(Deserialize, PartialEq, Debug)]
335 struct NestOne {
336     nest2: NestTwo,
337 }
338 
339 #[derive(Deserialize, PartialEq, Debug)]
340 struct NestTwo {
341     nest3: NestThree,
342 }
343 
344 #[derive(Deserialize, PartialEq, Debug)]
345 struct NestThree {
346     nest4: NestFour,
347 }
348 
349 #[derive(Deserialize, PartialEq, Debug)]
350 struct NestFour;
351 
352 #[derive(Deserialize, PartialEq, Debug)]
353 struct 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]
sdv_adapt_serde_example_three()363 fn 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