| # Serde JSON   [![Build Status]][travis] [![Latest Version]][crates.io] [![Rustc Version 1.31+]][rustc] |
| |
| [Build Status]: https://img.shields.io/github/workflow/status/serde-rs/json/CI/master |
| [travis]: https://github.com/serde-rs/json/actions?query=branch%3Amaster |
| [Latest Version]: https://img.shields.io/crates/v/serde_json.svg |
| [crates.io]: https://crates.io/crates/serde\_json |
| [Rustc Version 1.31+]: https://img.shields.io/badge/rustc-1.31+-lightgray.svg |
| [rustc]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html |
| |
| **Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** |
| |
| --- |
| |
| ```toml |
| [dependencies] |
| serde_json = "1.0" |
| ``` |
| |
| You may be looking for: |
| |
| - [JSON API documentation](https://docs.serde.rs/serde_json/) |
| - [Serde API documentation](https://docs.serde.rs/serde/) |
| - [Detailed documentation about Serde](https://serde.rs/) |
| - [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) |
| - [Release notes](https://github.com/serde-rs/json/releases) |
| |
| JSON is a ubiquitous open-standard format that uses human-readable text to |
| transmit data objects consisting of key-value pairs. |
| |
| ```json |
| { |
| "name": "John Doe", |
| "age": 43, |
| "address": { |
| "street": "10 Downing Street", |
| "city": "London" |
| }, |
| "phones": [ |
| "+44 1234567", |
| "+44 2345678" |
| ] |
| } |
| ``` |
| |
| There are three common ways that you might find yourself needing to work |
| with JSON data in Rust. |
| |
| - **As text data.** An unprocessed string of JSON data that you receive on |
| an HTTP endpoint, read from a file, or prepare to send to a remote |
| server. |
| - **As an untyped or loosely typed representation.** Maybe you want to |
| check that some JSON data is valid before passing it on, but without |
| knowing the structure of what it contains. Or you want to do very basic |
| manipulations like insert a key in a particular spot. |
| - **As a strongly typed Rust data structure.** When you expect all or most |
| of your data to conform to a particular structure and want to get real |
| work done without JSON's loosey-goosey nature tripping you up. |
| |
| Serde JSON provides efficient, flexible, safe ways of converting data |
| between each of these representations. |
| |
| ## Operating on untyped JSON values |
| |
| Any valid JSON data can be manipulated in the following recursive enum |
| representation. This data structure is [`serde_json::Value`][value]. |
| |
| ```rust |
| enum Value { |
| Null, |
| Bool(bool), |
| Number(Number), |
| String(String), |
| Array(Vec<Value>), |
| Object(Map<String, Value>), |
| } |
| ``` |
| |
| A string of JSON data can be parsed into a `serde_json::Value` by the |
| [`serde_json::from_str`][from_str] function. There is also |
| [`from_slice`][from_slice] for parsing from a byte slice &[u8] and |
| [`from_reader`][from_reader] for parsing from any `io::Read` like a File or |
| a TCP stream. |
| |
| <div align="right"> |
| <a href="https://play.rust-lang.org/?edition=2018&gist=d69d8e3156d4bb81c4461b60b772ab72" target="_blank"> |
| <img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png"> |
| </a> |
| </div> |
| |
| ```rust |
| use serde_json::{Result, Value}; |
| |
| fn untyped_example() -> Result<()> { |
| // Some JSON input data as a &str. Maybe this comes from the user. |
| let data = r#" |
| { |
| "name": "John Doe", |
| "age": 43, |
| "phones": [ |
| "+44 1234567", |
| "+44 2345678" |
| ] |
| }"#; |
| |
| // Parse the string of data into serde_json::Value. |
| let v: Value = serde_json::from_str(data)?; |
| |
| // Access parts of the data by indexing with square brackets. |
| println!("Please call {} at the number {}", v["name"], v["phones"][0]); |
| |
| Ok(()) |
| } |
| ``` |
| |
| The result of square bracket indexing like `v["name"]` is a borrow of the data |
| at that index, so the type is `&Value`. A JSON map can be indexed with string |
| keys, while a JSON array can be indexed with integer keys. If the type of the |
| data is not right for the type with which it is being indexed, or if a map does |
| not contain the key being indexed, or if the index into a vector is out of |
| bounds, the returned element is `Value::Null`. |
| |
| When a `Value` is printed, it is printed as a JSON string. So in the code above, |
| the output looks like `Please call "John Doe" at the number "+44 1234567"`. The |
| quotation marks appear because `v["name"]` is a `&Value` containing a JSON |
| string and its JSON representation is `"John Doe"`. Printing as a plain string |
| without quotation marks involves converting from a JSON string to a Rust string |
| with [`as_str()`] or avoiding the use of `Value` as described in the following |
| section. |
| |
| [`as_str()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.as_str |
| |
| The `Value` representation is sufficient for very basic tasks but can be tedious |
| to work with for anything more significant. Error handling is verbose to |
| implement correctly, for example imagine trying to detect the presence of |
| unrecognized fields in the input data. The compiler is powerless to help you |
| when you make a mistake, for example imagine typoing `v["name"]` as `v["nmae"]` |
| in one of the dozens of places it is used in your code. |
| |
| ## Parsing JSON as strongly typed data structures |
| |
| Serde provides a powerful way of mapping JSON data into Rust data structures |
| largely automatically. |
| |
| <div align="right"> |
| <a href="https://play.rust-lang.org/?edition=2018&gist=15cfab66d38ff8a15a9cf1d8d897ac68" target="_blank"> |
| <img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png"> |
| </a> |
| </div> |
| |
| ```rust |
| use serde::{Deserialize, Serialize}; |
| use serde_json::Result; |
| |
| #[derive(Serialize, Deserialize)] |
| struct Person { |
| name: String, |
| age: u8, |
| phones: Vec<String>, |
| } |
| |
| fn typed_example() -> Result<()> { |
| // Some JSON input data as a &str. Maybe this comes from the user. |
| let data = r#" |
| { |
| "name": "John Doe", |
| "age": 43, |
| "phones": [ |
| "+44 1234567", |
| "+44 2345678" |
| ] |
| }"#; |
| |
| // Parse the string of data into a Person object. This is exactly the |
| // same function as the one that produced serde_json::Value above, but |
| // now we are asking it for a Person as output. |
| let p: Person = serde_json::from_str(data)?; |
| |
| // Do things just like with any other Rust data structure. |
| println!("Please call {} at the number {}", p.name, p.phones[0]); |
| |
| Ok(()) |
| } |
| ``` |
| |
| This is the same `serde_json::from_str` function as before, but this time we |
| assign the return value to a variable of type `Person` so Serde will |
| automatically interpret the input data as a `Person` and produce informative |
| error messages if the layout does not conform to what a `Person` is expected |
| to look like. |
| |
| Any type that implements Serde's `Deserialize` trait can be deserialized |
| this way. This includes built-in Rust standard library types like `Vec<T>` |
| and `HashMap<K, V>`, as well as any structs or enums annotated with |
| `#[derive(Deserialize)]`. |
| |
| Once we have `p` of type `Person`, our IDE and the Rust compiler can help us |
| use it correctly like they do for any other Rust code. The IDE can |
| autocomplete field names to prevent typos, which was impossible in the |
| `serde_json::Value` representation. And the Rust compiler can check that |
| when we write `p.phones[0]`, then `p.phones` is guaranteed to be a |
| `Vec<String>` so indexing into it makes sense and produces a `String`. |
| |
| The necessary setup for using Serde's derive macros is explained on the *[Using |
| derive]* page of the Serde site. |
| |
| [Using derive]: https://serde.rs/derive.html |
| |
| ## Constructing JSON values |
| |
| Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` |
| objects with very natural JSON syntax. |
| |
| <div align="right"> |
| <a href="https://play.rust-lang.org/?edition=2018&gist=6ccafad431d72b62e77cc34c8e879b24" target="_blank"> |
| <img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png"> |
| </a> |
| </div> |
| |
| ```rust |
| use serde_json::json; |
| |
| fn main() { |
| // The type of `john` is `serde_json::Value` |
| let john = json!({ |
| "name": "John Doe", |
| "age": 43, |
| "phones": [ |
| "+44 1234567", |
| "+44 2345678" |
| ] |
| }); |
| |
| println!("first phone number: {}", john["phones"][0]); |
| |
| // Convert to a string of JSON and print it out |
| println!("{}", john.to_string()); |
| } |
| ``` |
| |
| The `Value::to_string()` function converts a `serde_json::Value` into a |
| `String` of JSON text. |
| |
| One neat thing about the `json!` macro is that variables and expressions can |
| be interpolated directly into the JSON value as you are building it. Serde |
| will check at compile time that the value you are interpolating is able to |
| be represented as JSON. |
| |
| <div align="right"> |
| <a href="https://play.rust-lang.org/?edition=2018&gist=f9101a6e61dfc9e02c6a67f315ed24f2" target="_blank"> |
| <img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png"> |
| </a> |
| </div> |
| |
| ```rust |
| let full_name = "John Doe"; |
| let age_last_year = 42; |
| |
| // The type of `john` is `serde_json::Value` |
| let john = json!({ |
| "name": full_name, |
| "age": age_last_year + 1, |
| "phones": [ |
| format!("+44 {}", random_phone()) |
| ] |
| }); |
| ``` |
| |
| This is amazingly convenient but we have the problem we had before with |
| `Value` which is that the IDE and Rust compiler cannot help us if we get it |
| wrong. Serde JSON provides a better way of serializing strongly-typed data |
| structures into JSON text. |
| |
| ## Creating JSON by serializing data structures |
| |
| A data structure can be converted to a JSON string by |
| [`serde_json::to_string`][to_string]. There is also |
| [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and |
| [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` |
| such as a File or a TCP stream. |
| |
| <div align="right"> |
| <a href="https://play.rust-lang.org/?edition=2018&gist=3472242a08ed2ff88a944f2a2283b0ee" target="_blank"> |
| <img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png"> |
| </a> |
| </div> |
| |
| ```rust |
| use serde::{Deserialize, Serialize}; |
| use serde_json::Result; |
| |
| #[derive(Serialize, Deserialize)] |
| struct Address { |
| street: String, |
| city: String, |
| } |
| |
| fn print_an_address() -> Result<()> { |
| // Some data structure. |
| let address = Address { |
| street: "10 Downing Street".to_owned(), |
| city: "London".to_owned(), |
| }; |
| |
| // Serialize it to a JSON string. |
| let j = serde_json::to_string(&address)?; |
| |
| // Print, write to a file, or send to an HTTP server. |
| println!("{}", j); |
| |
| Ok(()) |
| } |
| ``` |
| |
| Any type that implements Serde's `Serialize` trait can be serialized this |
| way. This includes built-in Rust standard library types like `Vec<T>` and |
| `HashMap<K, V>`, as well as any structs or enums annotated with |
| `#[derive(Serialize)]`. |
| |
| ## Performance |
| |
| It is fast. You should expect in the ballpark of 500 to 1000 megabytes per |
| second deserialization and 600 to 900 megabytes per second serialization, |
| depending on the characteristics of your data. This is competitive with the |
| fastest C and C++ JSON libraries or even 30% faster for many use cases. |
| Benchmarks live in the [serde-rs/json-benchmark] repo. |
| |
| [serde-rs/json-benchmark]: https://github.com/serde-rs/json-benchmark |
| |
| ## Getting help |
| |
| Serde is one of the most widely used Rust libraries so any place that Rustaceans |
| congregate will be able to help you out. For chat, consider trying the |
| [#general] or [#beginners] channels of the unofficial community Discord, the |
| [#rust-usage] channel of the official Rust Project Discord, or the |
| [#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag |
| on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned |
| weekly easy questions post, or the Rust [Discourse forum][discourse]. It's |
| acceptable to file a support issue in this repo but they tend not to get as many |
| eyes as any of the above and may get closed without a response after some time. |
| |
| [#general]: https://discord.com/channels/273534239310479360/274215136414400513 |
| [#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 |
| [#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 |
| [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general |
| [stackoverflow]: https://stackoverflow.com/questions/tagged/rust |
| [/r/rust]: https://www.reddit.com/r/rust |
| [discourse]: https://users.rust-lang.org |
| |
| ## No-std support |
| |
| As long as there is a memory allocator, it is possible to use serde_json without |
| the rest of the Rust standard library. This is supported on Rust 1.36+. Disable |
| the default "std" feature and enable the "alloc" feature: |
| |
| ```toml |
| [dependencies] |
| serde_json = { version = "1.0", default-features = false, features = ["alloc"] } |
| ``` |
| |
| For JSON support in Serde without a memory allocator, please see the |
| [`serde-json-core`] crate. |
| |
| [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core |
| |
| [value]: https://docs.serde.rs/serde_json/value/enum.Value.html |
| [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html |
| [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html |
| [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html |
| [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html |
| [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html |
| [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html |
| [macro]: https://docs.serde.rs/serde_json/macro.json.html |
| |
| <br> |
| |
| #### License |
| |
| <sup> |
| Licensed under either of <a href="LICENSE-APACHE">Apache License, Version |
| 2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. |
| </sup> |
| |
| <br> |
| |
| <sub> |
| Unless you explicitly state otherwise, any contribution intentionally submitted |
| for inclusion in this crate by you, as defined in the Apache-2.0 license, shall |
| be dual licensed as above, without any additional terms or conditions. |
| </sub> |