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