| 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.135" )] |
| 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" )))] |
| 369 | compile_error! { |
| 370 | "serde_json requires that either `std` (default) or `alloc` feature is enabled" |
| 371 | } |
| 372 | |
| 373 | extern crate alloc; |
| 374 | |
| 375 | #[cfg (feature = "std" )] |
| 376 | extern crate std; |
| 377 | |
| 378 | // Not public API. Used from macro-generated code. |
| 379 | #[doc (hidden)] |
| 380 | pub 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)] |
| 388 | pub use crate::de::from_reader; |
| 389 | #[doc (inline)] |
| 390 | pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer}; |
| 391 | #[doc (inline)] |
| 392 | pub use crate::error::{Error, Result}; |
| 393 | #[doc (inline)] |
| 394 | pub 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)] |
| 398 | pub use crate::ser::{to_writer, to_writer_pretty, Serializer}; |
| 399 | #[doc (inline)] |
| 400 | pub 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%. |
| 404 | macro_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 ] |
| 414 | mod macros; |
| 415 | |
| 416 | pub mod de; |
| 417 | pub mod error; |
| 418 | pub mod map; |
| 419 | #[cfg (feature = "std" )] |
| 420 | #[cfg_attr (docsrs, doc(cfg(feature = "std" )))] |
| 421 | pub mod ser; |
| 422 | #[cfg (not(feature = "std" ))] |
| 423 | mod ser; |
| 424 | pub mod value; |
| 425 | |
| 426 | mod io; |
| 427 | #[cfg (feature = "std" )] |
| 428 | mod iter; |
| 429 | #[cfg (feature = "float_roundtrip" )] |
| 430 | mod lexical; |
| 431 | mod number; |
| 432 | mod read; |
| 433 | |
| 434 | #[cfg (feature = "raw_value" )] |
| 435 | mod raw; |
| 436 | |