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