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()`]: crate::Value::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`: the IDE and Rust compiler cannot help us if we get it wrong. Serde 232 //! JSON provides a better way of serializing strongly-typed data structures 233 //! 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. Disable the default "std" 283 //! 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]: crate::value::Value 294 //! [from_str]: crate::de::from_str 295 //! [from_slice]: crate::de::from_slice 296 //! [from_reader]: crate::de::from_reader 297 //! [to_string]: crate::ser::to_string 298 //! [to_vec]: crate::ser::to_vec 299 //! [to_writer]: crate::ser::to_writer 300 //! [macro]: crate::json 301 //! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core 302 303 #![doc(html_root_url = "https://docs.rs/serde_json/1.0.94")] 304 // Ignored clippy lints 305 #![allow( 306 clippy::collapsible_else_if, 307 clippy::comparison_chain, 308 clippy::deprecated_cfg_attr, 309 clippy::doc_markdown, 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 bug: https://github.com/rust-lang/rust-clippy/issues/8366 319 clippy::ptr_arg, 320 clippy::return_self_not_must_use, 321 clippy::transmute_ptr_to_ptr, 322 clippy::unnecessary_wraps, 323 // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 324 clippy::unnested_or_patterns, 325 )] 326 // Ignored clippy_pedantic lints 327 #![allow( 328 // buggy 329 clippy::iter_not_returning_iterator, // https://github.com/rust-lang/rust-clippy/issues/8285 330 // Deserializer::from_str, into_iter 331 clippy::should_implement_trait, 332 // integer and float ser/de requires these sorts of casts 333 clippy::cast_possible_truncation, 334 clippy::cast_possible_wrap, 335 clippy::cast_precision_loss, 336 clippy::cast_sign_loss, 337 // correctly used 338 clippy::enum_glob_use, 339 clippy::if_not_else, 340 clippy::integer_division, 341 clippy::let_underscore_untyped, 342 clippy::map_err_ignore, 343 clippy::match_same_arms, 344 clippy::similar_names, 345 clippy::unused_self, 346 clippy::wildcard_imports, 347 // things are often more readable this way 348 clippy::cast_lossless, 349 clippy::module_name_repetitions, 350 clippy::redundant_else, 351 clippy::shadow_unrelated, 352 clippy::single_match_else, 353 clippy::too_many_lines, 354 clippy::unreadable_literal, 355 clippy::unseparated_literal_suffix, 356 clippy::use_self, 357 clippy::zero_prefixed_literal, 358 // we support older compilers 359 clippy::checked_conversions, 360 clippy::mem_replace_with_default, 361 // noisy 362 clippy::missing_errors_doc, 363 clippy::must_use_candidate, 364 )] 365 #![allow(non_upper_case_globals)] 366 #![deny(missing_docs)] 367 #![cfg_attr(not(feature = "std"), no_std)] 368 #![cfg_attr(docsrs, feature(doc_cfg))] 369 370 extern crate alloc; 371 372 #[cfg(feature = "std")] 373 #[doc(inline)] 374 pub use crate::de::from_reader; 375 #[doc(inline)] 376 pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer}; 377 #[doc(inline)] 378 pub use crate::error::{Error, Result}; 379 #[doc(inline)] 380 pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty}; 381 #[cfg(feature = "std")] 382 #[doc(inline)] 383 pub use crate::ser::{to_writer, to_writer_pretty, Serializer}; 384 #[doc(inline)] 385 pub use crate::value::{from_value, to_value, Map, Number, Value}; 386 387 // We only use our own error type; no need for From conversions provided by the 388 // standard library's try! macro. This reduces lines of LLVM IR by 4%. 389 macro_rules! tri { 390 ($e:expr $(,)?) => { 391 match $e { 392 core::result::Result::Ok(val) => val, 393 core::result::Result::Err(err) => return core::result::Result::Err(err), 394 } 395 }; 396 } 397 398 #[macro_use] 399 mod macros; 400 401 pub mod de; 402 pub mod error; 403 pub mod map; 404 #[cfg(feature = "std")] 405 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 406 pub mod ser; 407 #[cfg(not(feature = "std"))] 408 mod ser; 409 pub mod value; 410 411 mod features_check; 412 413 mod io; 414 #[cfg(feature = "std")] 415 mod iter; 416 #[cfg(feature = "float_roundtrip")] 417 mod lexical; 418 mod number; 419 mod read; 420 421 #[cfg(feature = "raw_value")] 422 mod raw; 423