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