serde_json_v8/lib.rs
1//! # Serde JSON V8
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//! ```edition2018
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//! ```edition2018
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()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.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//! ```edition2018
122//! # use serde_derive::{Deserialize, Serialize};
123//! use serde::{Deserialize, Serialize};
124//! use serde_json::Result;
125//!
126//! #[derive(Serialize, Deserialize)]
127//! struct Person {
128//! name: String,
129//! age: u8,
130//! phones: Vec<String>,
131//! }
132//!
133//! fn typed_example() -> Result<()> {
134//! // Some JSON input data as a &str. Maybe this comes from the user.
135//! let data = r#"
136//! {
137//! "name": "John Doe",
138//! "age": 43,
139//! "phones": [
140//! "+44 1234567",
141//! "+44 2345678"
142//! ]
143//! }"#;
144//!
145//! // Parse the string of data into a Person object. This is exactly the
146//! // same function as the one that produced serde_json::Value above, but
147//! // now we are asking it for a Person as output.
148//! let p: Person = serde_json::from_str(data)?;
149//!
150//! // Do things just like with any other Rust data structure.
151//! println!("Please call {} at the number {}", p.name, p.phones[0]);
152//!
153//! Ok(())
154//! }
155//! #
156//! # fn main() {
157//! # typed_example().unwrap();
158//! # }
159//! ```
160//!
161//! This is the same `serde_json::from_str` function as before, but this time we
162//! assign the return value to a variable of type `Person` so Serde will
163//! automatically interpret the input data as a `Person` and produce informative
164//! error messages if the layout does not conform to what a `Person` is expected
165//! to look like.
166//!
167//! Any type that implements Serde's `Deserialize` trait can be deserialized
168//! this way. This includes built-in Rust standard library types like `Vec<T>`
169//! and `HashMap<K, V>`, as well as any structs or enums annotated with
170//! `#[derive(Deserialize)]`.
171//!
172//! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us
173//! use it correctly like they do for any other Rust code. The IDE can
174//! autocomplete field names to prevent typos, which was impossible in the
175//! `serde_json::Value` representation. And the Rust compiler can check that
176//! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a
177//! `Vec<String>` so indexing into it makes sense and produces a `String`.
178//!
179//! # Constructing JSON values
180//!
181//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value`
182//! objects with very natural JSON syntax.
183//!
184//! ```edition2018
185//! use serde_json::json;
186//!
187//! fn main() {
188//! // The type of `john` is `serde_json::Value`
189//! let john = json!({
190//! "name": "John Doe",
191//! "age": 43,
192//! "phones": [
193//! "+44 1234567",
194//! "+44 2345678"
195//! ]
196//! });
197//!
198//! println!("first phone number: {}", john["phones"][0]);
199//!
200//! // Convert to a string of JSON and print it out
201//! println!("{}", john.to_string());
202//! }
203//! ```
204//!
205//! The `Value::to_string()` function converts a `serde_json::Value` into a
206//! `String` of JSON text.
207//!
208//! One neat thing about the `json!` macro is that variables and expressions can
209//! be interpolated directly into the JSON value as you are building it. Serde
210//! will check at compile time that the value you are interpolating is able to
211//! be represented as JSON.
212//!
213//! ```edition2018
214//! # use serde_json::json;
215//! #
216//! # fn random_phone() -> u16 { 0 }
217//! #
218//! let full_name = "John Doe";
219//! let age_last_year = 42;
220//!
221//! // The type of `john` is `serde_json::Value`
222//! let john = json!({
223//! "name": full_name,
224//! "age": age_last_year + 1,
225//! "phones": [
226//! format!("+44 {}", random_phone())
227//! ]
228//! });
229//! ```
230//!
231//! This is amazingly convenient but we have the problem we had before with
232//! `Value` which is that the IDE and Rust compiler cannot help us if we get it
233//! wrong. Serde JSON provides a better way of serializing strongly-typed data
234//! structures into JSON text.
235//!
236//! # Creating JSON by serializing data structures
237//!
238//! A data structure can be converted to a JSON string by
239//! [`serde_json::to_string`][to_string]. There is also
240//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and
241//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write`
242//! such as a File or a TCP stream.
243//!
244//! ```edition2018
245//! # use serde_derive::{Deserialize, Serialize};
246//! use serde::{Deserialize, Serialize};
247//! use serde_json::Result;
248//!
249//! #[derive(Serialize, Deserialize)]
250//! struct Address {
251//! street: String,
252//! city: String,
253//! }
254//!
255//! fn print_an_address() -> Result<()> {
256//! // Some data structure.
257//! let address = Address {
258//! street: "10 Downing Street".to_owned(),
259//! city: "London".to_owned(),
260//! };
261//!
262//! // Serialize it to a JSON string.
263//! let j = serde_json::to_string(&address)?;
264//!
265//! // Print, write to a file, or send to an HTTP server.
266//! println!("{}", j);
267//!
268//! Ok(())
269//! }
270//! #
271//! # fn main() {
272//! # print_an_address().unwrap();
273//! # }
274//! ```
275//!
276//! Any type that implements Serde's `Serialize` trait can be serialized this
277//! way. This includes built-in Rust standard library types like `Vec<T>` and
278//! `HashMap<K, V>`, as well as any structs or enums annotated with
279//! `#[derive(Serialize)]`.
280//!
281//! # No-std support
282//!
283//! This crate currently requires the Rust standard library. For JSON support in
284//! Serde without a standard library, please see the [`serde-json-core`] crate.
285//!
286//! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html
287//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
288//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
289//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
290//! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html
291//! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html
292//! [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html
293//! [macro]: https://docs.serde.rs/serde_json/macro.json.html
294//! [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/
295
296#![doc(html_root_url = "https://docs.rs/serde_json_v8/0.1.0")]
297#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
298#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
299// Ignored clippy lints
300#![cfg_attr(feature = "cargo-clippy", allow(deprecated_cfg_attr, doc_markdown))]
301// Ignored clippy_pedantic lints
302#![cfg_attr(feature = "cargo-clippy", allow(
303 // Deserializer::from_str, into_iter
304 should_implement_trait,
305 // integer and float ser/de requires these sorts of casts
306 cast_possible_wrap,
307 cast_precision_loss,
308 cast_sign_loss,
309 // things are often more readable this way
310 cast_lossless,
311 module_name_repetitions,
312 shadow_unrelated,
313 single_match_else,
314 use_self,
315 zero_prefixed_literal,
316 // we support older compilers
317 redundant_field_names,
318))]
319#![deny(missing_docs)]
320
321#[macro_use]
322extern crate serde;
323extern crate serde_json;
324#[cfg(feature = "preserve_order")]
325extern crate indexmap;
326extern crate itoa;
327extern crate ryu_js;
328
329#[doc(inline)]
330pub use serde_json::de::{from_reader, from_slice, from_str, Deserializer, StreamDeserializer};
331#[doc(inline)]
332pub use serde_json::error::{Error, Result};
333#[doc(inline)]
334pub use self::ser::{
335 to_string, to_string_pretty, to_vec, to_vec_pretty, to_writer, to_writer_pretty, Serializer,
336};
337#[doc(inline)]
338pub use self::value::{from_value, to_value, Map, Number, Value};
339
340// We only use our own error type; no need for From conversions provided by the
341// standard library's try! macro. This reduces lines of LLVM IR by 4%.
342macro_rules! try {
343 ($e:expr) => {
344 match $e {
345 ::std::result::Result::Ok(val) => val,
346 ::std::result::Result::Err(err) => return ::std::result::Result::Err(err),
347 }
348 };
349}
350
351// #[macro_use]
352// mod macros;
353
354pub use serde_json::de;
355pub use serde_json::error;
356pub use serde_json::map;
357pub mod ser;
358pub use serde_json::value;