1a1d56debSopenharmony_ci# ylong_json User Guide
2a1d56debSopenharmony_ci
3a1d56debSopenharmony_ciThe `ylong_json` module provides serialization of text or string in JSON syntax format, and deserialization of corresponding generated instances. In addition, the `ylong_json` module also adapts to the third-party library `serde`. Structures that implement specific traits in the `serde` library can be serialized and deserialized.
4a1d56debSopenharmony_ci
5a1d56debSopenharmony_ciIf you need to see the detailed interface description, please check the docs of the corresponding interface. You can use `cargo doc --open` to generate and view the docs.
6a1d56debSopenharmony_ci
7a1d56debSopenharmony_ci### Function 1: Generates a JSON instance
8a1d56debSopenharmony_ci`ylong_json` provides the ability to generate an instance of `JsonValue` from JSON text or string. You need to use a series of instance creation methods for the "JsonValue" to use this feature.
9a1d56debSopenharmony_ci
10a1d56debSopenharmony_ci(1) You can create a `JsonValue` instance by:
11a1d56debSopenharmony_ci```rust
12a1d56debSopenharmony_ciuse std::fs::File;
13a1d56debSopenharmony_ciuse std::str::FromStr;
14a1d56debSopenharmony_ciuse std::io::Read;
15a1d56debSopenharmony_ciuse ylong_json::JsonValue;
16a1d56debSopenharmony_cifn create_json_value_instance() {
17a1d56debSopenharmony_ci    let str: &str = "";
18a1d56debSopenharmony_ci    // You can use `from_str` to try to generate a `JsonValue` instance from 
19a1d56debSopenharmony_ci    // the &str type.
20a1d56debSopenharmony_ci    // If the passed &str does not conform to JSON syntax, the corresponding 
21a1d56debSopenharmony_ci    // Error will be returned.
22a1d56debSopenharmony_ci    let json_value = JsonValue::from_str(str);
23a1d56debSopenharmony_ci    
24a1d56debSopenharmony_ci    let text: String = String::from("");
25a1d56debSopenharmony_ci    // You can use `from_text` to generate a `JsonValue` instance from 
26a1d56debSopenharmony_ci    // a series of types that implement AsRef<[u8]>.
27a1d56debSopenharmony_ci    // If the passed text content does not conform to JSON syntax, the 
28a1d56debSopenharmony_ci    // corresponding Error will be returned.
29a1d56debSopenharmony_ci    let json_value = JsonValue::from_text(text);
30a1d56debSopenharmony_ci    
31a1d56debSopenharmony_ci    let path: &str = "";
32a1d56debSopenharmony_ci    // You can use `from_file` to read a file from corresponding path and 
33a1d56debSopenharmony_ci    // try to generate a `JsonValue` instance.
34a1d56debSopenharmony_ci    // If the passed path is not valid or the text content does not conform 
35a1d56debSopenharmony_ci    // to JSON syntax, the corresponding Error will be returned.
36a1d56debSopenharmony_ci    let json_value = JsonValue::from_file(path);
37a1d56debSopenharmony_ci    
38a1d56debSopenharmony_ci    let mut reader: Box<dyn Read> = Box::new(File::open("").unwrap());
39a1d56debSopenharmony_ci    // You can use `from_reader` interface to read text from an instance 
40a1d56debSopenharmony_ci    // that implements io::Read and try to generate a `JsonValue` instance.
41a1d56debSopenharmony_ci    // If the read fails or if the content from the reader does not conform
42a1d56debSopenharmony_ci    // to JSON syntax, the corresponding Error will be returned.
43a1d56debSopenharmony_ci    let json_value = JsonValue::from_reader(&mut reader);
44a1d56debSopenharmony_ci}
45a1d56debSopenharmony_ci```
46a1d56debSopenharmony_ciOnce the `JsonValue` instance has been successfully created, you can attempt to read and modify the corresponding contents.
47a1d56debSopenharmony_ci
48a1d56debSopenharmony_ci(2) If the type in the JSON text implements the third-party library `serde::Deserialize` trait, you can directly deserialize the text content to an instance of that type.
49a1d56debSopenharmony_ci```rust
50a1d56debSopenharmony_ciuse std::fs::File;
51a1d56debSopenharmony_ciuse serde::Deserialize;
52a1d56debSopenharmony_ciuse ylong_json::deserializer::{from_reader, from_slice, from_st};
53a1d56debSopenharmony_cifn deserialize_json_to_instance() {
54a1d56debSopenharmony_ci    #[derive(Deserialize, PartialEq, Debug)]
55a1d56debSopenharmony_ci    struct Example {
56a1d56debSopenharmony_ci        int: u32,
57a1d56debSopenharmony_ci        seq: Vec<String>,
58a1d56debSopenharmony_ci        tup: (i32, i32, i32),
59a1d56debSopenharmony_ci    }
60a1d56debSopenharmony_ci
61a1d56debSopenharmony_ci    // You can use `from_str` to try to generate an instance from String.
62a1d56debSopenharmony_ci    // If the passed String does not conform to JSON syntax, the corresponding
63a1d56debSopenharmony_ci    // Error will be returned.
64a1d56debSopenharmony_ci    let str = r#"{"int":1,"seq":["abcd","efgh"],"tup":[1,2,3]}"#;
65a1d56debSopenharmony_ci    let example = from_str::<Example>(str).unwrap();
66a1d56debSopenharmony_ci
67a1d56debSopenharmony_ci    // You can use `from_slice` to try to generate an instance from &u8.
68a1d56debSopenharmony_ci    // If the passed &u8 does not conform to JSON syntax, the corresponding
69a1d56debSopenharmony_ci    // Error will be returned.
70a1d56debSopenharmony_ci    let slice = str.as_bytes();
71a1d56debSopenharmony_ci    let example = from_slice::<Example>(slice).unwrap();
72a1d56debSopenharmony_ci
73a1d56debSopenharmony_ci    // You can use `from_reader` to try to generate an instance from 
74a1d56debSopenharmony_ci    // locations, files, io streams, and so on that implement io::Write.
75a1d56debSopenharmony_ci    // If the passed text content does not conform to JSON syntax, 
76a1d56debSopenharmony_ci    // the corresponding Error will be returned.
77a1d56debSopenharmony_ci    let mut file: File = File::open("./example.txt").unwrap();
78a1d56debSopenharmony_ci    let example = from_reader::<Example>(file).unwrap();
79a1d56debSopenharmony_ci}
80a1d56debSopenharmony_ci```
81a1d56debSopenharmony_ci
82a1d56debSopenharmony_ci### Function 2: Reads and modifies a key-value pair
83a1d56debSopenharmony_ciAfter a `JsonValue` instance is successfully generated, you can use a subscript to find the corresponding key-value pair (to obtain a common reference to the corresponding `JsonValue`).
84a1d56debSopenharmony_ci
85a1d56debSopenharmony_ciA subscript of type &str or String can be used to find a key-value pair in Object; 
86a1d56debSopenharmony_ciA Subscript of type usize can be used to find a key-value pair in an Array.
87a1d56debSopenharmony_ci```rust
88a1d56debSopenharmony_ciuse std::str::FromStr;
89a1d56debSopenharmony_ciuse ylong_json::JsonValue;
90a1d56debSopenharmony_ci
91a1d56debSopenharmony_ci// JSON string for the example
92a1d56debSopenharmony_ciconst JSON_TEXT: &str = r#"
93a1d56debSopenharmony_ci{
94a1d56debSopenharmony_ci    "key": "value",
95a1d56debSopenharmony_ci    "array": [1, 2, 3]
96a1d56debSopenharmony_ci}
97a1d56debSopenharmony_ci"#;
98a1d56debSopenharmony_ci
99a1d56debSopenharmony_cifn find_key_value_pair() {
100a1d56debSopenharmony_ci    // Creates a JsonValue instance from the example string, the syntax is 
101a1d56debSopenharmony_ci    // correct so the parse must succeed here, so uses unwrap.
102a1d56debSopenharmony_ci    let json_value = JsonValue::from_str(JSON_TEXT).unwrap();
103a1d56debSopenharmony_ci
104a1d56debSopenharmony_ci    // Since json is itself a table, you can use the &str type to obtain
105a1d56debSopenharmony_ci    // a common reference to the internal value.
106a1d56debSopenharmony_ci    let value: &JsonValue = &json_value["key"];
107a1d56debSopenharmony_ci
108a1d56debSopenharmony_ci    // You can use the &str type to obtain a common reference to the "array" member, and
109a1d56debSopenharmony_ci    // then use the usize type to obtain a common reference to the corresponding element.
110a1d56debSopenharmony_ci    let array_item: &JsonValue = &json_value["array"][0];
111a1d56debSopenharmony_ci
112a1d56debSopenharmony_ci    // If you try to find a key that does not exist in a table, 
113a1d56debSopenharmony_ci    // `&JsonValue::Null` will be returned.
114a1d56debSopenharmony_ci    let no_such_key: &JsonValue = &json_value["no_such_key"];
115a1d56debSopenharmony_ci
116a1d56debSopenharmony_ci    // When searching for the Array type, if the subscript exceeds the Array length, 
117a1d56debSopenharmony_ci    // `&JsonValue::Null` will also be returned.
118a1d56debSopenharmony_ci    let no_such_index: &JsonValue = &json_value["array"][100];
119a1d56debSopenharmony_ci
120a1d56debSopenharmony_ci    // If you use a subscript to visit `JsonValue` types other than Object and Array, 
121a1d56debSopenharmony_ci    // `&JsonValue::Null` will also be returned.
122a1d56debSopenharmony_ci    let invalid_index: &JsonValue = &json_value["key"]["invalid"];
123a1d56debSopenharmony_ci    let invalid_index: &JsonValue = &json_value["key"][0];
124a1d56debSopenharmony_ci}
125a1d56debSopenharmony_ci```
126a1d56debSopenharmony_ciYou can also use the same method to obtain a mutable reference to `JsonValue`. 
127a1d56debSopenharmony_ciAfter obtaining the mutable reference, you can modify it, but you need to make sure that it conforms to JSON syntax.
128a1d56debSopenharmony_ci```rust
129a1d56debSopenharmony_ciuse ylong_json::JsonValue;
130a1d56debSopenharmony_ci
131a1d56debSopenharmony_ci// JSON string for the example
132a1d56debSopenharmony_ciconst JSON_TEXT: &str = r#"
133a1d56debSopenharmony_ci{
134a1d56debSopenharmony_ci    "key": "value",
135a1d56debSopenharmony_ci    "array": [1, 2, 3]
136a1d56debSopenharmony_ci}
137a1d56debSopenharmony_ci"#;
138a1d56debSopenharmony_ci
139a1d56debSopenharmony_cifn modify_key_value_pair() {
140a1d56debSopenharmony_ci    // Creates a JsonValue instance from the example string, the syntax is
141a1d56debSopenharmony_ci    // correct so the parse must succeed here, so uses unwrap.
142a1d56debSopenharmony_ci    // Here the JSON instance needs to be mutable because you need to obtain a mutable reference.
143a1d56debSopenharmony_ci    let mut json_value = JsonValue::from_str(JSON_TEXT).unwrap();
144a1d56debSopenharmony_ci    
145a1d56debSopenharmony_ci    // Obtains a mutable reference to the member by "key" and set it to the number 123.
146a1d56debSopenharmony_ci    // In the libraty, many primitive types implement conversion from themselves to JsonValue, 
147a1d56debSopenharmony_ci    // so they can be converted to `JsonValue` by using `into()` method.
148a1d56debSopenharmony_ci    // After executing this code, the contents of the table are as follows:
149a1d56debSopenharmony_ci    // {
150a1d56debSopenharmony_ci    //      "key": 123,
151a1d56debSopenharmony_ci    //      "array": [1, 2, 3]
152a1d56debSopenharmony_ci    // }
153a1d56debSopenharmony_ci    json_value["key"] = 123_i32.into();
154a1d56debSopenharmony_ci    
155a1d56debSopenharmony_ci    // Obtains a mutable reference to the member by using "array" and the subscript 0,
156a1d56debSopenharmony_ci    // and set it to the number 123.
157a1d56debSopenharmony_ci    // After executing this code, the contents of the table are as follows:
158a1d56debSopenharmony_ci    // {
159a1d56debSopenharmony_ci    //      "key": 123,
160a1d56debSopenharmony_ci    //      "array": [123, 2, 3]
161a1d56debSopenharmony_ci    // }
162a1d56debSopenharmony_ci    json_value["array"][0] = 123_i32.into();
163a1d56debSopenharmony_ci   
164a1d56debSopenharmony_ci    // If you try to obtain a mutable reference to a key that does not exist in the table, 
165a1d56debSopenharmony_ci    // then the key will be inserted in the table with the corresponding value JsonValue::Null,
166a1d56debSopenharmony_ci    // and changes the value baesd on that.
167a1d56debSopenharmony_ci    // After executing this code, the json_value member "no_such_key" has been added, 
168a1d56debSopenharmony_ci    // and the value is 123.
169a1d56debSopenharmony_ci    // The contents of the table are as follows:
170a1d56debSopenharmony_ci    // {
171a1d56debSopenharmony_ci    //      "key": 123,
172a1d56debSopenharmony_ci    //      "array": [123, 2, 3],
173a1d56debSopenharmony_ci    //      "no_such_key": 123
174a1d56debSopenharmony_ci    // }
175a1d56debSopenharmony_ci    json_value["no_such_key"] = 123_i32.into();
176a1d56debSopenharmony_ci    
177a1d56debSopenharmony_ci    // When trying to obtain a mutable reference to a member of the Array type, if the 
178a1d56debSopenharmony_ci    // subscript exceeds the Array length, then a `JsonValue::Null` will be added at 
179a1d56debSopenharmony_ci    // the end of the Array and will return a mutable reference to that position.
180a1d56debSopenharmony_ci    // After executing this code, the length of the array member of `json_value` becomes 4, 
181a1d56debSopenharmony_ci    // and the value of the last member is 123.
182a1d56debSopenharmony_ci    // The contents of the table are as follows:
183a1d56debSopenharmony_ci    // {
184a1d56debSopenharmony_ci    //      "key": 123,
185a1d56debSopenharmony_ci    //      "array": [123, 2, 3, 123],
186a1d56debSopenharmony_ci    //      "no_such_key": 123
187a1d56debSopenharmony_ci    // }
188a1d56debSopenharmony_ci    json_value["array"][100] = 123_i32.into();
189a1d56debSopenharmony_ci    
190a1d56debSopenharmony_ci    // When using a subscript of &str type or String type to obtain a mutable reference to
191a1d56debSopenharmony_ci    // a non-Object type, will replace the value with an empty Object and then visit it with
192a1d56debSopenharmony_ci    // that subscript.
193a1d56debSopenharmony_ci    // After executing this code, the array member of `json_value` becomes of type Object 
194a1d56debSopenharmony_ci    // and contains a key-value pair: "key" => 123.
195a1d56debSopenharmony_ci    // The contents of the table are as follows:
196a1d56debSopenharmony_ci    // {
197a1d56debSopenharmony_ci    //      "key": 123,
198a1d56debSopenharmony_ci    //      "array": {
199a1d56debSopenharmony_ci    //          "key": 123
200a1d56debSopenharmony_ci    //      },
201a1d56debSopenharmony_ci    //      "no_such_key": 123
202a1d56debSopenharmony_ci    // }
203a1d56debSopenharmony_ci    json_value["array"]["key"] = 123_i32.into();
204a1d56debSopenharmony_ci    
205a1d56debSopenharmony_ci    // When using a subscript of usize type to obtain a mutable reference to a non-Array
206a1d56debSopenharmony_ci    // type, will replace the value with an empty Array and then visit it with that subscript.
207a1d56debSopenharmony_ci    // After executing this code, the key member of `json_value` becomes of type Array, 
208a1d56debSopenharmony_ci    // and contains a member: key[0] => 123.
209a1d56debSopenharmony_ci    // The contents of the table are as follows:
210a1d56debSopenharmony_ci    // {
211a1d56debSopenharmony_ci    //      "key": [123],
212a1d56debSopenharmony_ci    //      "array": {
213a1d56debSopenharmony_ci    //          "key": 123
214a1d56debSopenharmony_ci    //      },
215a1d56debSopenharmony_ci    //      "no_such_key": 123
216a1d56debSopenharmony_ci    // }
217a1d56debSopenharmony_ci    json_value["key"][0] = 123_i32.into();
218a1d56debSopenharmony_ci}
219a1d56debSopenharmony_ci```
220a1d56debSopenharmony_ci
221a1d56debSopenharmony_ci### Function 3: Outputs JSON text
222a1d56debSopenharmony_ci(1) When you have a JsonValue instance, you can convert it to text and output it to a specified location: string, file, network, etc.
223a1d56debSopenharmony_ci```rust
224a1d56debSopenharmony_ciuse std::fs::File;
225a1d56debSopenharmony_ciuse ylong_json::JsonValue;
226a1d56debSopenharmony_ci
227a1d56debSopenharmony_cifn output_json_text(json_value: JsonValue) {
228a1d56debSopenharmony_ci    // Uses `to_compact_string()` to output the `json_value` as a string.
229a1d56debSopenharmony_ci    let string = json_value.to_compact_string().unwrap();
230a1d56debSopenharmony_ci
231a1d56debSopenharmony_ci    // Uses `compact_encode()` to output JSON text to a specified location,  
232a1d56debSopenharmony_ci    // file, io stream, etc., which implements io::Write.
233a1d56debSopenharmony_ci    let mut file: File = File::open("").unwrap();
234a1d56debSopenharmony_ci    let _ = json_value.compact_encode(&mut file);
235a1d56debSopenharmony_ci}
236a1d56debSopenharmony_ci```
237a1d56debSopenharmony_ciBecause there is no strong order requirement for JSON internal elements, 
238a1d56debSopenharmony_cithe output order of members will have a certain randomness, 
239a1d56debSopenharmony_cibut it does not affect the semantics of JSON text.
240a1d56debSopenharmony_ci
241a1d56debSopenharmony_ci(2) You can also serialize an instance of a type that implements the `serde::Serialize` trait to JSON text.
242a1d56debSopenharmony_ci```rust
243a1d56debSopenharmony_ciuse std::fs::File;
244a1d56debSopenharmony_ciuse serde::Serialize;
245a1d56debSopenharmony_ciuse ylong_json::serializer_compact::{to_string, to_writer};
246a1d56debSopenharmony_ci
247a1d56debSopenharmony_cifn<V: Serialize> output_json_text(value: V) {
248a1d56debSopenharmony_ci    #[derive(Serialize)]
249a1d56debSopenharmony_ci    struct Exmaple {
250a1d56debSopenharmony_ci        int: u32,
251a1d56debSopenharmony_ci        seq: Vec<&'static str>,
252a1d56debSopenharmony_ci        tup: (i32, i32, i32),
253a1d56debSopenharmony_ci    }
254a1d56debSopenharmony_ci
255a1d56debSopenharmony_ci    let example = Example {
256a1d56debSopenharmony_ci        int: 1,
257a1d56debSopenharmony_ci        seq: vec!["a", "b"],
258a1d56debSopenharmony_ci        tup: (1, 2, 3),
259a1d56debSopenharmony_ci    };
260a1d56debSopenharmony_ci
261a1d56debSopenharmony_ci    // Uses `to_string()` to output the value as a string.
262a1d56debSopenharmony_ci    let string = to_string(&example).unwrap();
263a1d56debSopenharmony_ci
264a1d56debSopenharmony_ci    // Uses `to_writer()` to output JSON text to a specified location,
265a1d56debSopenharmony_ci    // file, io stream, etc., which implements io::Write.
266a1d56debSopenharmony_ci    let mut file: File = File::open("./example.txt").unwrap();
267a1d56debSopenharmony_ci    let _ = to_writer(&example, &mut file);
268a1d56debSopenharmony_ci}
269a1d56debSopenharmony_ci```