]>
Commit | Line | Data |
---|---|---|
041b39d2 XL |
1 | // Copyright 2017 Serde Developers |
2 | // | |
3 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
4 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
5 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
6 | // option. This file may not be copied, modified, or distributed | |
7 | // except according to those terms. | |
8 | ||
7cac9316 XL |
9 | //! # Serde JSON |
10 | //! | |
11 | //! JSON is a ubiquitous open-standard format that uses human-readable text to | |
12 | //! transmit data objects consisting of key-value pairs. | |
13 | //! | |
14 | //! ```json,ignore | |
15 | //! { | |
16 | //! "name": "John Doe", | |
17 | //! "age": 43, | |
18 | //! "address": { | |
19 | //! "street": "10 Downing Street", | |
20 | //! "city": "London" | |
21 | //! }, | |
22 | //! "phones": [ | |
23 | //! "+44 1234567", | |
24 | //! "+44 2345678" | |
25 | //! ] | |
26 | //! } | |
27 | //! ``` | |
28 | //! | |
29 | //! There are three common ways that you might find yourself needing to work | |
30 | //! with JSON data in Rust. | |
31 | //! | |
32 | //! - **As text data.** An unprocessed string of JSON data that you receive on | |
33 | //! an HTTP endpoint, read from a file, or prepare to send to a remote | |
34 | //! server. | |
35 | //! - **As an untyped or loosely typed representation.** Maybe you want to | |
36 | //! check that some JSON data is valid before passing it on, but without | |
37 | //! knowing the structure of what it contains. Or you want to do very basic | |
041b39d2 | 38 | //! manipulations like insert a key in a particular spot. |
7cac9316 XL |
39 | //! - **As a strongly typed Rust data structure.** When you expect all or most |
40 | //! of your data to conform to a particular structure and want to get real | |
41 | //! work done without JSON's loosey-goosey nature tripping you up. | |
42 | //! | |
43 | //! Serde JSON provides efficient, flexible, safe ways of converting data | |
44 | //! between each of these representations. | |
45 | //! | |
041b39d2 | 46 | //! # Operating on untyped JSON values |
7cac9316 XL |
47 | //! |
48 | //! Any valid JSON data can be manipulated in the following recursive enum | |
49 | //! representation. This data structure is [`serde_json::Value`][value]. | |
50 | //! | |
51 | //! ```rust | |
52 | //! # use serde_json::{Number, Map}; | |
041b39d2 | 53 | //! # |
7cac9316 XL |
54 | //! # #[allow(dead_code)] |
55 | //! enum Value { | |
56 | //! Null, | |
57 | //! Bool(bool), | |
58 | //! Number(Number), | |
59 | //! String(String), | |
60 | //! Array(Vec<Value>), | |
61 | //! Object(Map<String, Value>), | |
62 | //! } | |
63 | //! ``` | |
64 | //! | |
65 | //! A string of JSON data can be parsed into a `serde_json::Value` by the | |
66 | //! [`serde_json::from_str`][from_str] function. There is also | |
041b39d2 | 67 | //! [`from_slice`][from_slice] for parsing from a byte slice &[u8] and |
7cac9316 XL |
68 | //! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or |
69 | //! a TCP stream. | |
70 | //! | |
71 | //! ```rust | |
041b39d2 XL |
72 | //! extern crate serde_json; |
73 | //! | |
74 | //! use serde_json::{Value, Error}; | |
75 | //! | |
76 | //! fn untyped_example() -> Result<(), Error> { | |
77 | //! // Some JSON input data as a &str. Maybe this comes from the user. | |
78 | //! let data = r#"{ | |
79 | //! "name": "John Doe", | |
80 | //! "age": 43, | |
81 | //! "phones": [ | |
82 | //! "+44 1234567", | |
83 | //! "+44 2345678" | |
84 | //! ] | |
85 | //! }"#; | |
86 | //! | |
87 | //! // Parse the string of data into serde_json::Value. | |
88 | //! let v: Value = serde_json::from_str(data)?; | |
89 | //! | |
90 | //! // Access parts of the data by indexing with square brackets. | |
91 | //! println!("Please call {} at the number {}", v["name"], v["phones"][0]); | |
92 | //! | |
93 | //! Ok(()) | |
94 | //! } | |
95 | //! # | |
96 | //! # fn main() { | |
97 | //! # untyped_example().unwrap(); | |
98 | //! # } | |
7cac9316 XL |
99 | //! ``` |
100 | //! | |
abe05a73 XL |
101 | //! The result of square bracket indexing like `v["name"]` is a borrow of the |
102 | //! data at that index, so the type is `&Value`. A JSON map can be indexed with | |
103 | //! string keys, while a JSON array can be indexed with integer keys. If the | |
104 | //! type of the data is not right for the type with which it is being indexed, | |
105 | //! or if a map does not contain the key being indexed, or if the index into a | |
106 | //! vector is out of bounds, the returned element is `Value::Null`. | |
107 | //! | |
108 | //! When a `Value` is printed, it is printed as a JSON string. So in the code | |
109 | //! above, the output looks like `Please call "John Doe" at the number "+44 | |
110 | //! 1234567"`. The quotation marks appear because `v["name"]` is a `&Value` | |
111 | //! containing a JSON string and its JSON representation is `"John Doe"`. | |
112 | //! Printing as a plain string without quotation marks involves converting from | |
113 | //! a JSON string to a Rust string with [`as_str()`] or avoiding the use of | |
114 | //! `Value` as described in the following section. | |
115 | //! | |
116 | //! [`as_str()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.as_str | |
117 | //! | |
041b39d2 XL |
118 | //! The `Value` representation is sufficient for very basic tasks but can be |
119 | //! tedious to work with for anything more significant. Error handling is | |
120 | //! verbose to implement correctly, for example imagine trying to detect the | |
121 | //! presence of unrecognized fields in the input data. The compiler is powerless | |
122 | //! to help you when you make a mistake, for example imagine typoing `v["name"]` | |
123 | //! as `v["nmae"]` in one of the dozens of places it is used in your code. | |
7cac9316 | 124 | //! |
041b39d2 | 125 | //! # Parsing JSON as strongly typed data structures |
7cac9316 XL |
126 | //! |
127 | //! Serde provides a powerful way of mapping JSON data into Rust data structures | |
128 | //! largely automatically. | |
129 | //! | |
130 | //! ```rust | |
041b39d2 XL |
131 | //! extern crate serde; |
132 | //! extern crate serde_json; | |
133 | //! | |
134 | //! #[macro_use] | |
135 | //! extern crate serde_derive; | |
136 | //! | |
137 | //! use serde_json::Error; | |
138 | //! | |
7cac9316 XL |
139 | //! #[derive(Serialize, Deserialize)] |
140 | //! struct Person { | |
141 | //! name: String, | |
142 | //! age: u8, | |
7cac9316 XL |
143 | //! phones: Vec<String>, |
144 | //! } | |
145 | //! | |
041b39d2 XL |
146 | //! fn typed_example() -> Result<(), Error> { |
147 | //! // Some JSON input data as a &str. Maybe this comes from the user. | |
148 | //! let data = r#"{ | |
149 | //! "name": "John Doe", | |
150 | //! "age": 43, | |
151 | //! "phones": [ | |
152 | //! "+44 1234567", | |
153 | //! "+44 2345678" | |
154 | //! ] | |
155 | //! }"#; | |
156 | //! | |
157 | //! // Parse the string of data into a Person object. This is exactly the | |
158 | //! // same function as the one that produced serde_json::Value above, but | |
159 | //! // now we are asking it for a Person as output. | |
160 | //! let p: Person = serde_json::from_str(data)?; | |
161 | //! | |
162 | //! // Do things just like with any other Rust data structure. | |
163 | //! println!("Please call {} at the number {}", p.name, p.phones[0]); | |
164 | //! | |
165 | //! Ok(()) | |
7cac9316 | 166 | //! } |
041b39d2 XL |
167 | //! # |
168 | //! # fn main() { | |
169 | //! # typed_example().unwrap(); | |
170 | //! # } | |
7cac9316 XL |
171 | //! ``` |
172 | //! | |
173 | //! This is the same `serde_json::from_str` function as before, but this time we | |
041b39d2 | 174 | //! assign the return value to a variable of type `Person` so Serde will |
7cac9316 XL |
175 | //! automatically interpret the input data as a `Person` and produce informative |
176 | //! error messages if the layout does not conform to what a `Person` is expected | |
177 | //! to look like. | |
178 | //! | |
179 | //! Any type that implements Serde's `Deserialize` trait can be deserialized | |
180 | //! this way. This includes built-in Rust standard library types like `Vec<T>` | |
181 | //! and `HashMap<K, V>`, as well as any structs or enums annotated with | |
182 | //! `#[derive(Deserialize)]`. | |
183 | //! | |
184 | //! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us | |
185 | //! use it correctly like they do for any other Rust code. The IDE can | |
186 | //! autocomplete field names to prevent typos, which was impossible in the | |
187 | //! `serde_json::Value` representation. And the Rust compiler can check that | |
188 | //! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a | |
189 | //! `Vec<String>` so indexing into it makes sense and produces a `String`. | |
190 | //! | |
041b39d2 | 191 | //! # Constructing JSON values |
7cac9316 XL |
192 | //! |
193 | //! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` | |
194 | //! objects with very natural JSON syntax. In order to use this macro, | |
195 | //! `serde_json` needs to be imported with the `#[macro_use]` attribute. | |
196 | //! | |
197 | //! ```rust | |
198 | //! #[macro_use] | |
199 | //! extern crate serde_json; | |
200 | //! | |
201 | //! fn main() { | |
202 | //! // The type of `john` is `serde_json::Value` | |
203 | //! let john = json!({ | |
204 | //! "name": "John Doe", | |
205 | //! "age": 43, | |
206 | //! "phones": [ | |
207 | //! "+44 1234567", | |
208 | //! "+44 2345678" | |
209 | //! ] | |
210 | //! }); | |
211 | //! | |
212 | //! println!("first phone number: {}", john["phones"][0]); | |
213 | //! | |
214 | //! // Convert to a string of JSON and print it out | |
215 | //! println!("{}", john.to_string()); | |
216 | //! } | |
217 | //! ``` | |
218 | //! | |
219 | //! The `Value::to_string()` function converts a `serde_json::Value` into a | |
220 | //! `String` of JSON text. | |
221 | //! | |
222 | //! One neat thing about the `json!` macro is that variables and expressions can | |
223 | //! be interpolated directly into the JSON value as you are building it. Serde | |
224 | //! will check at compile time that the value you are interpolating is able to | |
225 | //! be represented as JSON. | |
226 | //! | |
227 | //! ```rust | |
041b39d2 XL |
228 | //! # #[macro_use] |
229 | //! # extern crate serde_json; | |
230 | //! # | |
7cac9316 | 231 | //! # fn random_phone() -> u16 { 0 } |
041b39d2 | 232 | //! # |
7cac9316 XL |
233 | //! # fn main() { |
234 | //! let full_name = "John Doe"; | |
235 | //! let age_last_year = 42; | |
236 | //! | |
237 | //! // The type of `john` is `serde_json::Value` | |
238 | //! let john = json!({ | |
239 | //! "name": full_name, | |
240 | //! "age": age_last_year + 1, | |
241 | //! "phones": [ | |
242 | //! format!("+44 {}", random_phone()) | |
243 | //! ] | |
244 | //! }); | |
041b39d2 | 245 | //! # let _ = john; |
7cac9316 XL |
246 | //! # } |
247 | //! ``` | |
248 | //! | |
249 | //! This is amazingly convenient but we have the problem we had before with | |
250 | //! `Value` which is that the IDE and Rust compiler cannot help us if we get it | |
251 | //! wrong. Serde JSON provides a better way of serializing strongly-typed data | |
252 | //! structures into JSON text. | |
253 | //! | |
041b39d2 | 254 | //! # Creating JSON by serializing data structures |
7cac9316 XL |
255 | //! |
256 | //! A data structure can be converted to a JSON string by | |
257 | //! [`serde_json::to_string`][to_string]. There is also | |
258 | //! [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and | |
259 | //! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` | |
260 | //! such as a File or a TCP stream. | |
261 | //! | |
262 | //! ```rust | |
041b39d2 XL |
263 | //! extern crate serde; |
264 | //! extern crate serde_json; | |
265 | //! | |
266 | //! #[macro_use] | |
267 | //! extern crate serde_derive; | |
268 | //! | |
269 | //! use serde_json::Error; | |
270 | //! | |
7cac9316 XL |
271 | //! #[derive(Serialize, Deserialize)] |
272 | //! struct Address { | |
273 | //! street: String, | |
274 | //! city: String, | |
275 | //! } | |
276 | //! | |
041b39d2 XL |
277 | //! fn print_an_address() -> Result<(), Error> { |
278 | //! // Some data structure. | |
279 | //! let address = Address { | |
280 | //! street: "10 Downing Street".to_owned(), | |
281 | //! city: "London".to_owned(), | |
282 | //! }; | |
283 | //! | |
284 | //! // Serialize it to a JSON string. | |
285 | //! let j = serde_json::to_string(&address)?; | |
7cac9316 | 286 | //! |
041b39d2 XL |
287 | //! // Print, write to a file, or send to an HTTP server. |
288 | //! println!("{}", j); | |
289 | //! | |
290 | //! Ok(()) | |
291 | //! } | |
292 | //! # | |
293 | //! # fn main() { | |
294 | //! # print_an_address().unwrap(); | |
295 | //! # } | |
7cac9316 XL |
296 | //! ``` |
297 | //! | |
298 | //! Any type that implements Serde's `Serialize` trait can be serialized this | |
299 | //! way. This includes built-in Rust standard library types like `Vec<T>` and | |
300 | //! `HashMap<K, V>`, as well as any structs or enums annotated with | |
301 | //! `#[derive(Serialize)]`. | |
302 | //! | |
83c7162d XL |
303 | //! # No-std support |
304 | //! | |
305 | //! This crate currently requires the Rust standard library. For JSON support in | |
306 | //! Serde without a standard library, please see the [`serde-json-core`] crate. | |
307 | //! | |
7cac9316 XL |
308 | //! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html |
309 | //! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html | |
310 | //! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html | |
7cac9316 XL |
311 | //! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html |
312 | //! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html | |
313 | //! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html | |
314 | //! [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html | |
315 | //! [macro]: https://docs.serde.rs/serde_json/macro.json.html | |
83c7162d | 316 | //! [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/ |
7cac9316 | 317 | |
b7449926 | 318 | #![doc(html_root_url = "https://docs.rs/serde_json/1.0.26")] |
7cac9316 | 319 | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] |
abe05a73 | 320 | // Whitelisted clippy lints |
8faf50e0 XL |
321 | #![cfg_attr( |
322 | feature = "cargo-clippy", | |
323 | allow(doc_markdown, needless_pass_by_value) | |
324 | )] | |
7cac9316 XL |
325 | // Whitelisted clippy_pedantic lints |
326 | #![cfg_attr(feature = "cargo-clippy", allow( | |
041b39d2 | 327 | // Deserializer::from_str, into_iter |
7cac9316 XL |
328 | should_implement_trait, |
329 | // integer and float ser/de requires these sorts of casts | |
330 | cast_possible_truncation, | |
331 | cast_possible_wrap, | |
332 | cast_precision_loss, | |
333 | cast_sign_loss, | |
334 | // string ser/de uses indexing and slicing | |
335 | indexing_slicing, | |
336 | // things are often more readable this way | |
ea8adc8c | 337 | cast_lossless, |
7cac9316 XL |
338 | shadow_reuse, |
339 | shadow_unrelated, | |
340 | single_match_else, | |
341 | stutter, | |
ea8adc8c | 342 | use_self, |
7cac9316 XL |
343 | // not practical |
344 | missing_docs_in_private_items, | |
0531ce1d XL |
345 | similar_names, |
346 | // we support older compilers | |
347 | redundant_field_names, | |
7cac9316 | 348 | ))] |
7cac9316 XL |
349 | #![deny(missing_docs)] |
350 | ||
7cac9316 XL |
351 | #[macro_use] |
352 | extern crate serde; | |
b7449926 | 353 | extern crate ryu; |
7cac9316 | 354 | #[cfg(feature = "preserve_order")] |
8faf50e0 XL |
355 | extern crate indexmap; |
356 | extern crate itoa; | |
7cac9316 XL |
357 | |
358 | #[doc(inline)] | |
83c7162d | 359 | pub use self::de::{from_reader, from_slice, from_str, Deserializer, StreamDeserializer}; |
7cac9316 XL |
360 | #[doc(inline)] |
361 | pub use self::error::{Error, Result}; | |
362 | #[doc(inline)] | |
8faf50e0 XL |
363 | pub use self::ser::{ |
364 | to_string, to_string_pretty, to_vec, to_vec_pretty, to_writer, to_writer_pretty, Serializer, | |
365 | }; | |
7cac9316 | 366 | #[doc(inline)] |
83c7162d | 367 | pub use self::value::{from_value, to_value, Map, Number, Value}; |
7cac9316 | 368 | |
ff7c6d11 XL |
369 | // We only use our own error type; no need for From conversions provided by the |
370 | // standard library's try! macro. This reduces lines of LLVM IR by 4%. | |
371 | macro_rules! try { | |
372 | ($e:expr) => { | |
373 | match $e { | |
374 | ::std::result::Result::Ok(val) => val, | |
83c7162d | 375 | ::std::result::Result::Err(err) => return ::std::result::Result::Err(err), |
ff7c6d11 | 376 | } |
83c7162d | 377 | }; |
ff7c6d11 XL |
378 | } |
379 | ||
7cac9316 XL |
380 | #[macro_use] |
381 | mod macros; | |
382 | ||
383 | pub mod de; | |
384 | pub mod error; | |
385 | pub mod map; | |
386 | pub mod ser; | |
387 | pub mod value; | |
388 | ||
041b39d2 | 389 | mod iter; |
7cac9316 XL |
390 | mod number; |
391 | mod read; |