serde_json/
lib.rs

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.138")]
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::excessive_precision,
310    clippy::explicit_auto_deref,
311    clippy::float_cmp,
312    clippy::manual_range_contains,
313    clippy::match_like_matches_macro,
314    clippy::match_single_binding,
315    clippy::needless_doctest_main,
316    clippy::needless_late_init,
317    clippy::needless_lifetimes,
318    clippy::return_self_not_must_use,
319    clippy::transmute_ptr_to_ptr,
320    clippy::unconditional_recursion, // https://github.com/rust-lang/rust-clippy/issues/12133
321    clippy::unnecessary_wraps
322)]
323// Ignored clippy_pedantic lints
324#![allow(
325    // Deserializer::from_str, into_iter
326    clippy::should_implement_trait,
327    // integer and float ser/de requires these sorts of casts
328    clippy::cast_possible_truncation,
329    clippy::cast_possible_wrap,
330    clippy::cast_precision_loss,
331    clippy::cast_sign_loss,
332    // correctly used
333    clippy::enum_glob_use,
334    clippy::if_not_else,
335    clippy::integer_division,
336    clippy::let_underscore_untyped,
337    clippy::map_err_ignore,
338    clippy::match_same_arms,
339    clippy::similar_names,
340    clippy::unused_self,
341    clippy::wildcard_imports,
342    // things are often more readable this way
343    clippy::cast_lossless,
344    clippy::items_after_statements,
345    clippy::module_name_repetitions,
346    clippy::redundant_else,
347    clippy::shadow_unrelated,
348    clippy::single_match_else,
349    clippy::too_many_lines,
350    clippy::unreadable_literal,
351    clippy::unseparated_literal_suffix,
352    clippy::use_self,
353    clippy::zero_prefixed_literal,
354    // we support older compilers
355    clippy::checked_conversions,
356    clippy::mem_replace_with_default,
357    // noisy
358    clippy::missing_errors_doc,
359    clippy::must_use_candidate,
360)]
361// Restrictions
362#![deny(clippy::question_mark_used)]
363#![allow(non_upper_case_globals)]
364#![deny(missing_docs)]
365#![no_std]
366#![cfg_attr(docsrs, feature(doc_cfg))]
367
368#[cfg(not(any(feature = "std", feature = "alloc")))]
369compile_error! {
370    "serde_json requires that either `std` (default) or `alloc` feature is enabled"
371}
372
373extern crate alloc;
374
375#[cfg(feature = "std")]
376extern crate std;
377
378// Not public API. Used from macro-generated code.
379#[doc(hidden)]
380pub mod __private {
381    #[doc(hidden)]
382    pub use alloc::vec;
383}
384
385#[cfg(feature = "std")]
386#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
387#[doc(inline)]
388pub use crate::de::from_reader;
389#[doc(inline)]
390pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer};
391#[doc(inline)]
392pub use crate::error::{Error, Result};
393#[doc(inline)]
394pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty};
395#[cfg(feature = "std")]
396#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
397#[doc(inline)]
398pub use crate::ser::{to_writer, to_writer_pretty, Serializer};
399#[doc(inline)]
400pub use crate::value::{from_value, to_value, Map, Number, Value};
401
402// We only use our own error type; no need for From conversions provided by the
403// standard library's try! macro. This reduces lines of LLVM IR by 4%.
404macro_rules! tri {
405    ($e:expr $(,)?) => {
406        match $e {
407            core::result::Result::Ok(val) => val,
408            core::result::Result::Err(err) => return core::result::Result::Err(err),
409        }
410    };
411}
412
413#[macro_use]
414mod macros;
415
416pub mod de;
417pub mod error;
418pub mod map;
419#[cfg(feature = "std")]
420#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
421pub mod ser;
422#[cfg(not(feature = "std"))]
423mod ser;
424pub mod value;
425
426mod io;
427#[cfg(feature = "std")]
428mod iter;
429#[cfg(feature = "float_roundtrip")]
430mod lexical;
431mod number;
432mod read;
433
434#[cfg(feature = "raw_value")]
435mod raw;