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 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 //! ``` 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 //! ``` 122 //! use serde::{Deserialize, Serialize}; 123 //! use serde_json::Result; 124 //! 125 //! #[derive(Serialize, Deserialize)] 126 //! struct Person { 127 //! name: String, 128 //! age: u8, 129 //! phones: Vec<String>, 130 //! } 131 //! 132 //! fn typed_example() -> Result<()> { 133 //! // Some JSON input data as a &str. Maybe this comes from the user. 134 //! let data = r#" 135 //! { 136 //! "name": "John Doe", 137 //! "age": 43, 138 //! "phones": [ 139 //! "+44 1234567", 140 //! "+44 2345678" 141 //! ] 142 //! }"#; 143 //! 144 //! // Parse the string of data into a Person object. This is exactly the 145 //! // same function as the one that produced serde_json::Value above, but 146 //! // now we are asking it for a Person as output. 147 //! let p: Person = serde_json::from_str(data)?; 148 //! 149 //! // Do things just like with any other Rust data structure. 150 //! println!("Please call {} at the number {}", p.name, p.phones[0]); 151 //! 152 //! Ok(()) 153 //! } 154 //! # 155 //! # fn main() { 156 //! # typed_example().unwrap(); 157 //! # } 158 //! ``` 159 //! 160 //! This is the same `serde_json::from_str` function as before, but this time we 161 //! assign the return value to a variable of type `Person` so Serde will 162 //! automatically interpret the input data as a `Person` and produce informative 163 //! error messages if the layout does not conform to what a `Person` is expected 164 //! to look like. 165 //! 166 //! Any type that implements Serde's `Deserialize` trait can be deserialized 167 //! this way. This includes built-in Rust standard library types like `Vec<T>` 168 //! and `HashMap<K, V>`, as well as any structs or enums annotated with 169 //! `#[derive(Deserialize)]`. 170 //! 171 //! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us 172 //! use it correctly like they do for any other Rust code. The IDE can 173 //! autocomplete field names to prevent typos, which was impossible in the 174 //! `serde_json::Value` representation. And the Rust compiler can check that 175 //! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a 176 //! `Vec<String>` so indexing into it makes sense and produces a `String`. 177 //! 178 //! # Constructing JSON values 179 //! 180 //! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` 181 //! objects with very natural JSON syntax. 182 //! 183 //! ``` 184 //! use serde_json::json; 185 //! 186 //! fn main() { 187 //! // The type of `john` is `serde_json::Value` 188 //! let john = json!({ 189 //! "name": "John Doe", 190 //! "age": 43, 191 //! "phones": [ 192 //! "+44 1234567", 193 //! "+44 2345678" 194 //! ] 195 //! }); 196 //! 197 //! println!("first phone number: {}", john["phones"][0]); 198 //! 199 //! // Convert to a string of JSON and print it out 200 //! println!("{}", john.to_string()); 201 //! } 202 //! ``` 203 //! 204 //! The `Value::to_string()` function converts a `serde_json::Value` into a 205 //! `String` of JSON text. 206 //! 207 //! One neat thing about the `json!` macro is that variables and expressions can 208 //! be interpolated directly into the JSON value as you are building it. Serde 209 //! will check at compile time that the value you are interpolating is able to 210 //! be represented as JSON. 211 //! 212 //! ``` 213 //! # use serde_json::json; 214 //! # 215 //! # fn random_phone() -> u16 { 0 } 216 //! # 217 //! let full_name = "John Doe"; 218 //! let age_last_year = 42; 219 //! 220 //! // The type of `john` is `serde_json::Value` 221 //! let john = json!({ 222 //! "name": full_name, 223 //! "age": age_last_year + 1, 224 //! "phones": [ 225 //! format!("+44 {}", random_phone()) 226 //! ] 227 //! }); 228 //! ``` 229 //! 230 //! This is amazingly convenient but we have the problem we had before with 231 //! `Value` which is that the IDE and Rust compiler cannot help us if we get it 232 //! wrong. Serde JSON provides a better way of serializing strongly-typed data 233 //! structures into JSON text. 234 //! 235 //! # Creating JSON by serializing data structures 236 //! 237 //! A data structure can be converted to a JSON string by 238 //! [`serde_json::to_string`][to_string]. There is also 239 //! [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and 240 //! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` 241 //! such as a File or a TCP stream. 242 //! 243 //! ``` 244 //! use serde::{Deserialize, Serialize}; 245 //! use serde_json::Result; 246 //! 247 //! #[derive(Serialize, Deserialize)] 248 //! struct Address { 249 //! street: String, 250 //! city: String, 251 //! } 252 //! 253 //! fn print_an_address() -> Result<()> { 254 //! // Some data structure. 255 //! let address = Address { 256 //! street: "10 Downing Street".to_owned(), 257 //! city: "London".to_owned(), 258 //! }; 259 //! 260 //! // Serialize it to a JSON string. 261 //! let j = serde_json::to_string(&address)?; 262 //! 263 //! // Print, write to a file, or send to an HTTP server. 264 //! println!("{}", j); 265 //! 266 //! Ok(()) 267 //! } 268 //! # 269 //! # fn main() { 270 //! # print_an_address().unwrap(); 271 //! # } 272 //! ``` 273 //! 274 //! Any type that implements Serde's `Serialize` trait can be serialized this 275 //! way. This includes built-in Rust standard library types like `Vec<T>` and 276 //! `HashMap<K, V>`, as well as any structs or enums annotated with 277 //! `#[derive(Serialize)]`. 278 //! 279 //! # No-std support 280 //! 281 //! As long as there is a memory allocator, it is possible to use serde_json 282 //! without the rest of the Rust standard library. This is supported on Rust 283 //! 1.36+. Disable the default "std" feature and enable the "alloc" feature: 284 //! 285 //! ```toml 286 //! [dependencies] 287 //! serde_json = { version = "1.0", default-features = false, features = ["alloc"] } 288 //! ``` 289 //! 290 //! For JSON support in Serde without a memory allocator, please see the 291 //! [`serde-json-core`] crate. 292 //! 293 //! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html 294 //! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html 295 //! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html 296 //! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html 297 //! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html 298 //! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html 299 //! [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html 300 //! [macro]: https://docs.serde.rs/serde_json/macro.json.html 301 //! [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/ 302 303 #![doc(html_root_url = "https://docs.rs/serde_json/1.0.62")] 304 #![deny(clippy::all, clippy::pedantic)] 305 // Ignored clippy lints 306 #![allow( 307 clippy::comparison_chain, 308 clippy::deprecated_cfg_attr, 309 clippy::doc_markdown, 310 clippy::excessive_precision, 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::transmute_ptr_to_ptr, 317 clippy::unnecessary_wraps, 318 // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 319 clippy::unnested_or_patterns, 320 )] 321 // Ignored clippy_pedantic lints 322 #![allow( 323 // Deserializer::from_str, into_iter 324 clippy::should_implement_trait, 325 // integer and float ser/de requires these sorts of casts 326 clippy::cast_possible_truncation, 327 clippy::cast_possible_wrap, 328 clippy::cast_precision_loss, 329 clippy::cast_sign_loss, 330 // correctly used 331 clippy::enum_glob_use, 332 clippy::if_not_else, 333 clippy::integer_division, 334 clippy::map_err_ignore, 335 clippy::match_same_arms, 336 clippy::similar_names, 337 clippy::unused_self, 338 clippy::wildcard_imports, 339 // things are often more readable this way 340 clippy::cast_lossless, 341 clippy::module_name_repetitions, 342 clippy::redundant_else, 343 clippy::shadow_unrelated, 344 clippy::single_match_else, 345 clippy::too_many_lines, 346 clippy::unreadable_literal, 347 clippy::unseparated_literal_suffix, 348 clippy::use_self, 349 clippy::zero_prefixed_literal, 350 // we support older compilers 351 clippy::checked_conversions, 352 clippy::mem_replace_with_default, 353 // noisy 354 clippy::missing_errors_doc, 355 clippy::must_use_candidate, 356 )] 357 #![allow(non_upper_case_globals)] 358 #![deny(missing_docs)] 359 #![cfg_attr(not(feature = "std"), no_std)] 360 361 //////////////////////////////////////////////////////////////////////////////// 362 363 #[cfg(not(feature = "std"))] 364 extern crate alloc; 365 366 /// A facade around all the types we need from the `std`, `core`, and `alloc` 367 /// crates. This avoids elaborate import wrangling having to happen in every 368 /// module. 369 mod lib { 370 mod core { 371 #[cfg(not(feature = "std"))] 372 pub use core::*; 373 #[cfg(feature = "std")] 374 pub use std::*; 375 } 376 377 pub use self::core::cell::{Cell, RefCell}; 378 pub use self::core::clone::{self, Clone}; 379 pub use self::core::convert::{self, From, Into}; 380 pub use self::core::default::{self, Default}; 381 pub use self::core::fmt::{self, Debug, Display}; 382 pub use self::core::hash::{self, Hash}; 383 pub use self::core::iter::FusedIterator; 384 pub use self::core::marker::{self, PhantomData}; 385 pub use self::core::ops::{Bound, RangeBounds}; 386 pub use self::core::result::{self, Result}; 387 pub use self::core::{borrow, char, cmp, iter, mem, num, ops, slice, str}; 388 389 #[cfg(not(feature = "std"))] 390 pub use alloc::borrow::{Cow, ToOwned}; 391 #[cfg(feature = "std")] 392 pub use std::borrow::{Cow, ToOwned}; 393 394 #[cfg(not(feature = "std"))] 395 pub use alloc::string::{String, ToString}; 396 #[cfg(feature = "std")] 397 pub use std::string::{String, ToString}; 398 399 #[cfg(not(feature = "std"))] 400 pub use alloc::vec::{self, Vec}; 401 #[cfg(feature = "std")] 402 pub use std::vec::{self, Vec}; 403 404 #[cfg(not(feature = "std"))] 405 pub use alloc::boxed::Box; 406 #[cfg(feature = "std")] 407 pub use std::boxed::Box; 408 409 #[cfg(not(feature = "std"))] 410 pub use alloc::collections::{btree_map, BTreeMap}; 411 #[cfg(feature = "std")] 412 pub use std::collections::{btree_map, BTreeMap}; 413 414 #[cfg(feature = "std")] 415 pub use std::error; 416 } 417 418 //////////////////////////////////////////////////////////////////////////////// 419 420 #[cfg(feature = "std")] 421 #[doc(inline)] 422 pub use crate::de::from_reader; 423 #[doc(inline)] 424 pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer}; 425 #[doc(inline)] 426 pub use crate::error::{Error, Result}; 427 #[doc(inline)] 428 pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty}; 429 #[cfg(feature = "std")] 430 #[doc(inline)] 431 pub use crate::ser::{to_writer, to_writer_pretty, Serializer}; 432 #[doc(inline)] 433 pub use crate::value::{from_value, to_value, Map, Number, Value}; 434 435 // We only use our own error type; no need for From conversions provided by the 436 // standard library's try! macro. This reduces lines of LLVM IR by 4%. 437 macro_rules! tri { 438 ($e:expr) => { 439 match $e { 440 crate::lib::Result::Ok(val) => val, 441 crate::lib::Result::Err(err) => return crate::lib::Result::Err(err), 442 } 443 }; 444 ($e:expr,) => { 445 tri!($e) 446 }; 447 } 448 449 #[macro_use] 450 mod macros; 451 452 pub mod de; 453 pub mod error; 454 pub mod map; 455 #[cfg(feature = "std")] 456 pub mod ser; 457 #[cfg(not(feature = "std"))] 458 mod ser; 459 pub mod value; 460 461 mod features_check; 462 463 mod io; 464 #[cfg(feature = "std")] 465 mod iter; 466 #[cfg(feature = "float_roundtrip")] 467 mod lexical; 468 mod number; 469 mod read; 470 471 #[cfg(feature = "raw_value")] 472 mod raw; 473