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