├── tests ├── regression │ ├── mod.rs │ └── issue520.rs ├── crate │ ├── test.rs │ └── Cargo.toml ├── ui │ ├── missing_colon.rs │ ├── not_found.rs │ ├── parse_expr.rs │ ├── missing_value.rs │ ├── parse_key.rs │ ├── unexpected_colon.rs │ ├── unexpected_comma.rs │ ├── unexpected_after_array_element.rs │ ├── unexpected_after_map_entry.rs │ ├── unexpected_colon.stderr │ ├── unexpected_comma.stderr │ ├── parse_key.stderr │ ├── unexpected_after_array_element.stderr │ ├── unexpected_after_map_entry.stderr │ ├── not_found.stderr │ ├── missing_colon.stderr │ ├── missing_value.stderr │ └── parse_expr.stderr ├── regression.rs ├── compiletest.rs ├── preserve_order.rs ├── debug.rs ├── macros │ └── mod.rs └── stream.rs ├── .gitignore ├── appveyor.yml ├── LICENSE-MIT ├── .travis.yml ├── src ├── iter.rs ├── value │ ├── partial_eq.rs │ ├── from.rs │ └── index.rs ├── macros.rs ├── lib.rs ├── raw.rs ├── error.rs ├── number.rs ├── map.rs └── read.rs ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE └── README.md /tests/regression/mod.rs: -------------------------------------------------------------------------------- 1 | automod::dir!("tests/regression"); 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | **/*.rs.bk 3 | *.sw[po] 4 | Cargo.lock 5 | -------------------------------------------------------------------------------- /tests/crate/test.rs: -------------------------------------------------------------------------------- 1 | extern crate serde_json; 2 | pub use serde_json::*; 3 | -------------------------------------------------------------------------------- /tests/ui/missing_colon.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/not_found.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" : x }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/parse_expr.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" : ~ }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/missing_value.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" : }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/parse_key.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "".s : true }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_colon.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ : true }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_comma.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" , "b": true }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_after_array_element.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!([ true => ]); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_after_map_entry.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "k": true => }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/regression.rs: -------------------------------------------------------------------------------- 1 | extern crate automod; 2 | extern crate serde; 3 | extern crate serde_derive; 4 | 5 | #[path = "regression/mod.rs"] 6 | mod regression; 7 | -------------------------------------------------------------------------------- /tests/compiletest.rs: -------------------------------------------------------------------------------- 1 | #[rustversion::attr(not(nightly), ignore)] 2 | #[test] 3 | fn ui() { 4 | let t = trybuild::TestCases::new(); 5 | t.compile_fail("tests/ui/*.rs"); 6 | } 7 | -------------------------------------------------------------------------------- /tests/ui/unexpected_colon.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected the token `:` 2 | --> $DIR/unexpected_colon.rs:4:13 3 | | 4 | 4 | json!({ : true }); 5 | | ^ no rules expected this token in macro call 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_comma.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected the token `,` 2 | --> $DIR/unexpected_comma.rs:4:17 3 | | 4 | 4 | json!({ "a" , "b": true }); 5 | | ^ no rules expected this token in macro call 6 | -------------------------------------------------------------------------------- /tests/ui/parse_key.stderr: -------------------------------------------------------------------------------- 1 | error[E0609]: no field `s` on type `&'static str` 2 | --> $DIR/parse_key.rs:4:16 3 | | 4 | 4 | json!({ "".s : true }); 5 | | ^ 6 | 7 | For more information about this error, try `rustc --explain E0609`. 8 | -------------------------------------------------------------------------------- /tests/ui/unexpected_after_array_element.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected the token `=>` 2 | --> $DIR/unexpected_after_array_element.rs:4:18 3 | | 4 | 4 | json!([ true => ]); 5 | | ^^ no rules expected this token in macro call 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_after_map_entry.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected the token `=>` 2 | --> $DIR/unexpected_after_map_entry.rs:4:23 3 | | 4 | 4 | json!({ "k": true => }); 5 | | ^^ no rules expected this token in macro call 6 | -------------------------------------------------------------------------------- /tests/ui/not_found.stderr: -------------------------------------------------------------------------------- 1 | error[E0425]: cannot find value `x` in this scope 2 | --> $DIR/not_found.rs:4:19 3 | | 4 | 4 | json!({ "a" : x }); 5 | | ^ not found in this scope 6 | 7 | For more information about this error, try `rustc --explain E0425`. 8 | -------------------------------------------------------------------------------- /tests/ui/missing_colon.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of macro invocation 2 | --> $DIR/missing_colon.rs:4:5 3 | | 4 | 4 | json!({ "a" }); 5 | | ^^^^^^^^^^^^^^^ missing tokens in macro arguments 6 | | 7 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/ui/missing_value.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of macro invocation 2 | --> $DIR/missing_value.rs:4:5 3 | | 4 | 4 | json!({ "a" : }); 5 | | ^^^^^^^^^^^^^^^^^ missing tokens in macro arguments 6 | | 7 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/ui/parse_expr.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of macro invocation 2 | --> $DIR/parse_expr.rs:4:5 3 | | 4 | 4 | json!({ "a" : ~ }); 5 | | ^^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments 6 | | 7 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_json_test" 3 | version = "0.0.0" 4 | publish = false 5 | 6 | [lib] 7 | path = "test.rs" 8 | 9 | [dependencies] 10 | serde_json = { path = "../.." } 11 | 12 | [features] 13 | arbitrary_precision = ["serde_json/arbitrary_precision"] 14 | preserve_order = ["serde_json/preserve_order"] 15 | raw_value = ["serde_json/raw_value"] 16 | unbounded_depth = ["serde_json/unbounded_depth"] 17 | -------------------------------------------------------------------------------- /tests/regression/issue520.rs: -------------------------------------------------------------------------------- 1 | use serde_derive::{Serialize, Deserialize}; 2 | 3 | #[derive(Serialize, Deserialize, Debug)] 4 | #[serde(tag = "type", content = "data")] 5 | enum E { 6 | Float(f32), 7 | } 8 | 9 | #[test] 10 | fn test() { 11 | let e = E::Float(159.1); 12 | let v = serde_json::to_value(e).unwrap(); 13 | let e = serde_json::from_value::(v).unwrap(); 14 | 15 | match e { 16 | E::Float(f) => assert_eq!(f, 159.1), 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/preserve_order.rs: -------------------------------------------------------------------------------- 1 | extern crate serde_json; 2 | 3 | use serde_json::{from_str, Value}; 4 | 5 | #[test] 6 | fn test_map_order() { 7 | // Sorted order 8 | #[cfg(not(feature = "preserve_order"))] 9 | const EXPECTED: &[&str] = &["a", "b", "c"]; 10 | 11 | // Insertion order 12 | #[cfg(feature = "preserve_order")] 13 | const EXPECTED: &[&str] = &["b", "a", "c"]; 14 | 15 | let v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); 16 | let keys: Vec<_> = v.as_object().unwrap().keys().collect(); 17 | assert_eq!(keys, EXPECTED); 18 | } 19 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - APPVEYOR_RUST_CHANNEL: stable 4 | - APPVEYOR_RUST_CHANNEL: nightly 5 | 6 | install: 7 | # Install rust, x86_64-pc-windows-msvc host 8 | - curl -sSf -o rustup-init.exe https://win.rustup.rs/ 9 | - rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain %APPVEYOR_RUST_CHANNEL% 10 | - set PATH=C:\msys64\usr\bin;%PATH%;C:\Users\appveyor\.cargo\bin 11 | - rustc -vV 12 | - cargo -vV 13 | 14 | build: false 15 | 16 | for: 17 | - matrix: 18 | only: 19 | - APPVEYOR_RUST_CHANNEL: stable 20 | test_script: 21 | - cargo build 22 | - cargo build --features preserve_order 23 | - cargo build --features arbitrary_precision 24 | 25 | - matrix: 26 | only: 27 | - APPVEYOR_RUST_CHANNEL: nightly 28 | test_script: 29 | - cargo build 30 | - cargo test 31 | - cargo test --features preserve_order 32 | - cargo test --features arbitrary_precision 33 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | 3 | matrix: 4 | include: 5 | - rust: nightly 6 | script: 7 | - cargo test 8 | - cargo test --features preserve_order 9 | - cargo test --features arbitrary_precision 10 | - cargo test --features raw_value 11 | - cargo test --features unbounded_depth 12 | 13 | - rust: 1.15.0 14 | script: 15 | # preserve_order is not supported on 1.15.0 16 | - cargo build --manifest-path tests/crate/Cargo.toml 17 | - cargo build --manifest-path tests/crate/Cargo.toml --features arbitrary_precision 18 | 19 | - rust: 1.18.0 20 | script: 21 | - cargo build --manifest-path tests/crate/Cargo.toml 22 | - cargo build --manifest-path tests/crate/Cargo.toml --features preserve_order 23 | - cargo build --manifest-path tests/crate/Cargo.toml --features arbitrary_precision 24 | 25 | - rust: stable 26 | - rust: beta 27 | - rust: 1.31.0 28 | 29 | - rust: nightly 30 | name: Clippy 31 | script: 32 | - rustup component add clippy || travis_terminate 0 33 | - cargo clippy 34 | 35 | script: 36 | - cargo build 37 | - cargo build --features preserve_order 38 | - cargo build --features arbitrary_precision 39 | -------------------------------------------------------------------------------- /tests/debug.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate serde_json; 3 | 4 | use serde_json::{Number, Value}; 5 | 6 | #[test] 7 | fn number() { 8 | assert_eq!(format!("{:?}", Number::from(1)), "Number(1)"); 9 | assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)"); 10 | assert_eq!( 11 | format!("{:?}", Number::from_f64(1.0).unwrap()), 12 | "Number(1.0)" 13 | ); 14 | } 15 | 16 | #[test] 17 | fn value_null() { 18 | assert_eq!(format!("{:?}", json!(null)), "Null"); 19 | } 20 | 21 | #[test] 22 | fn value_bool() { 23 | assert_eq!(format!("{:?}", json!(true)), "Bool(true)"); 24 | assert_eq!(format!("{:?}", json!(false)), "Bool(false)"); 25 | } 26 | 27 | #[test] 28 | fn value_number() { 29 | assert_eq!(format!("{:?}", json!(1)), "Number(1)"); 30 | assert_eq!(format!("{:?}", json!(-1)), "Number(-1)"); 31 | assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)"); 32 | } 33 | 34 | #[test] 35 | fn value_string() { 36 | assert_eq!(format!("{:?}", json!("s")), "String(\"s\")"); 37 | } 38 | 39 | #[test] 40 | fn value_array() { 41 | assert_eq!(format!("{:?}", json!([])), "Array([])"); 42 | } 43 | 44 | #[test] 45 | fn value_object() { 46 | assert_eq!(format!("{:?}", json!({})), "Object({})"); 47 | } 48 | 49 | #[test] 50 | fn error() { 51 | let err = serde_json::from_str::("{0}").unwrap_err(); 52 | let expected = "Error(\"key must be a string\", line: 1, column: 2)"; 53 | assert_eq!(format!("{:?}", err), expected); 54 | } 55 | -------------------------------------------------------------------------------- /tests/macros/mod.rs: -------------------------------------------------------------------------------- 1 | macro_rules! json_str { 2 | ([]) => { 3 | "[]" 4 | }; 5 | ([ $e1:tt $(, $e:tt)* ]) => { 6 | concat!("[", 7 | json_str!($e1), 8 | $(",", json_str!($e),)* 9 | "]") 10 | }; 11 | ({}) => { 12 | "{}" 13 | }; 14 | ({ $k1:tt : $v1:tt $(, $k:tt : $v:tt)* }) => { 15 | concat!("{", 16 | stringify!($k1), ":", json_str!($v1), 17 | $(",", stringify!($k), ":", json_str!($v),)* 18 | "}") 19 | }; 20 | (($other:tt)) => { 21 | $other 22 | }; 23 | ($other:tt) => { 24 | stringify!($other) 25 | }; 26 | } 27 | 28 | macro_rules! pretty_str { 29 | ($json:tt) => { 30 | pretty_str_impl!("", $json) 31 | }; 32 | } 33 | 34 | macro_rules! pretty_str_impl { 35 | ($indent:expr, []) => { 36 | "[]" 37 | }; 38 | ($indent:expr, [ $e1:tt $(, $e:tt)* ]) => { 39 | concat!("[\n ", 40 | $indent, pretty_str_impl!(concat!(" ", $indent), $e1), 41 | $(",\n ", $indent, pretty_str_impl!(concat!(" ", $indent), $e),)* 42 | "\n", $indent, "]") 43 | }; 44 | ($indent:expr, {}) => { 45 | "{}" 46 | }; 47 | ($indent:expr, { $k1:tt : $v1:tt $(, $k:tt : $v:tt)* }) => { 48 | concat!("{\n ", 49 | $indent, stringify!($k1), ": ", pretty_str_impl!(concat!(" ", $indent), $v1), 50 | $(",\n ", $indent, stringify!($k), ": ", pretty_str_impl!(concat!(" ", $indent), $v),)* 51 | "\n", $indent, "}") 52 | }; 53 | ($indent:expr, ($other:tt)) => { 54 | $other 55 | }; 56 | ($indent:expr, $other:tt) => { 57 | stringify!($other) 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /src/iter.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | pub struct LineColIterator { 4 | iter: I, 5 | 6 | /// Index of the current line. Characters in the first line of the input 7 | /// (before the first newline character) are in line 1. 8 | line: usize, 9 | 10 | /// Index of the current column. The first character in the input and any 11 | /// characters immediately following a newline character are in column 1. 12 | /// The column is 0 immediately after a newline character has been read. 13 | col: usize, 14 | 15 | /// Byte offset of the start of the current line. This is the sum of lenghts 16 | /// of all previous lines. Keeping track of things this way allows efficient 17 | /// computation of the current line, column, and byte offset while only 18 | /// updating one of the counters in `next()` in the common case. 19 | start_of_line: usize, 20 | } 21 | 22 | impl LineColIterator 23 | where 24 | I: Iterator>, 25 | { 26 | pub fn new(iter: I) -> LineColIterator { 27 | LineColIterator { 28 | iter: iter, 29 | line: 1, 30 | col: 0, 31 | start_of_line: 0, 32 | } 33 | } 34 | 35 | pub fn line(&self) -> usize { 36 | self.line 37 | } 38 | 39 | pub fn col(&self) -> usize { 40 | self.col 41 | } 42 | 43 | pub fn byte_offset(&self) -> usize { 44 | self.start_of_line + self.col 45 | } 46 | } 47 | 48 | impl Iterator for LineColIterator 49 | where 50 | I: Iterator>, 51 | { 52 | type Item = io::Result; 53 | 54 | fn next(&mut self) -> Option> { 55 | match self.iter.next() { 56 | None => None, 57 | Some(Ok(b'\n')) => { 58 | self.start_of_line += self.col + 1; 59 | self.line += 1; 60 | self.col = 0; 61 | Some(Ok(b'\n')) 62 | } 63 | Some(Ok(c)) => { 64 | self.col += 1; 65 | Some(Ok(c)) 66 | } 67 | Some(Err(e)) => Some(Err(e)), 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Serde 2 | 3 | Serde welcomes contribution from everyone in the form of suggestions, bug 4 | reports, pull requests, and feedback. This document gives some guidance if you 5 | are thinking of helping us. 6 | 7 | Please reach out here in a GitHub issue or in the #serde IRC channel on 8 | [`irc.mozilla.org`] if we can do anything to help you contribute. 9 | 10 | [`irc.mozilla.org`]: https://wiki.mozilla.org/IRC 11 | 12 | ## Submitting bug reports and feature requests 13 | 14 | Serde development is spread across lots of repositories. In general, prefer to 15 | open issues against the main [serde-rs/serde] repository unless the topic is 16 | clearly specific to JSON. 17 | 18 | [serde-rs/serde]: https://github.com/serde-rs/serde 19 | 20 | When reporting a bug or asking for help, please include enough details so that 21 | the people helping you can reproduce the behavior you are seeing. For some tips 22 | on how to approach this, read about how to produce a [Minimal, Complete, and 23 | Verifiable example]. 24 | 25 | [Minimal, Complete, and Verifiable example]: https://stackoverflow.com/help/mcve 26 | 27 | When making a feature request, please make it clear what problem you intend to 28 | solve with the feature, any ideas for how Serde could support solving that 29 | problem, any possible alternatives, and any disadvantages. 30 | 31 | ## Running the test suite 32 | 33 | We encourage you to check that the test suite passes locally before submitting a 34 | pull request with your changes. If anything does not pass, typically it will be 35 | easier to iterate and fix it locally than waiting for the CI servers to run 36 | tests for you. 37 | 38 | The test suite requires a nightly compiler. 39 | 40 | ##### In the [`tests/deps`] directory 41 | 42 | ```sh 43 | # This is a prerequisite for running the full test suite 44 | cargo clean && cargo update && cargo build 45 | ``` 46 | 47 | ##### In the top level serde-json directory 48 | 49 | ```sh 50 | # Run the full test suite, including doc test and compile-tests 51 | cargo test 52 | ``` 53 | 54 | [`tests/deps`]: https://github.com/serde-rs/json/tree/master/tests/deps 55 | 56 | ## Conduct 57 | 58 | In all Serde-related forums, we follow the [Rust Code of Conduct]. For 59 | escalation or moderation issues please contact Erick (erick.tryzelaar@gmail.com) 60 | instead of the Rust moderation team. 61 | 62 | [Rust Code of Conduct]: https://www.rust-lang.org/conduct.html 63 | -------------------------------------------------------------------------------- /src/value/partial_eq.rs: -------------------------------------------------------------------------------- 1 | use super::Value; 2 | 3 | fn eq_i64(value: &Value, other: i64) -> bool { 4 | value.as_i64().map_or(false, |i| i == other) 5 | } 6 | 7 | fn eq_u64(value: &Value, other: u64) -> bool { 8 | value.as_u64().map_or(false, |i| i == other) 9 | } 10 | 11 | fn eq_f64(value: &Value, other: f64) -> bool { 12 | value.as_f64().map_or(false, |i| i == other) 13 | } 14 | 15 | fn eq_bool(value: &Value, other: bool) -> bool { 16 | value.as_bool().map_or(false, |i| i == other) 17 | } 18 | 19 | fn eq_str(value: &Value, other: &str) -> bool { 20 | value.as_str().map_or(false, |i| i == other) 21 | } 22 | 23 | impl PartialEq for Value { 24 | fn eq(&self, other: &str) -> bool { 25 | eq_str(self, other) 26 | } 27 | } 28 | 29 | impl<'a> PartialEq<&'a str> for Value { 30 | fn eq(&self, other: &&str) -> bool { 31 | eq_str(self, *other) 32 | } 33 | } 34 | 35 | impl PartialEq for str { 36 | fn eq(&self, other: &Value) -> bool { 37 | eq_str(other, self) 38 | } 39 | } 40 | 41 | impl<'a> PartialEq for &'a str { 42 | fn eq(&self, other: &Value) -> bool { 43 | eq_str(other, *self) 44 | } 45 | } 46 | 47 | impl PartialEq for Value { 48 | fn eq(&self, other: &String) -> bool { 49 | eq_str(self, other.as_str()) 50 | } 51 | } 52 | 53 | impl PartialEq for String { 54 | fn eq(&self, other: &Value) -> bool { 55 | eq_str(other, self.as_str()) 56 | } 57 | } 58 | 59 | macro_rules! partialeq_numeric { 60 | ($($eq:ident [$($ty:ty)*])*) => { 61 | $($( 62 | impl PartialEq<$ty> for Value { 63 | fn eq(&self, other: &$ty) -> bool { 64 | $eq(self, *other as _) 65 | } 66 | } 67 | 68 | impl PartialEq for $ty { 69 | fn eq(&self, other: &Value) -> bool { 70 | $eq(other, *self as _) 71 | } 72 | } 73 | 74 | impl<'a> PartialEq<$ty> for &'a Value { 75 | fn eq(&self, other: &$ty) -> bool { 76 | $eq(*self, *other as _) 77 | } 78 | } 79 | 80 | impl<'a> PartialEq<$ty> for &'a mut Value { 81 | fn eq(&self, other: &$ty) -> bool { 82 | $eq(*self, *other as _) 83 | } 84 | } 85 | )*)* 86 | } 87 | } 88 | 89 | partialeq_numeric! { 90 | eq_i64[i8 i16 i32 i64 isize] 91 | eq_u64[u8 u16 u32 u64 usize] 92 | eq_f64[f32 f64] 93 | eq_bool[bool] 94 | } 95 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_json" 3 | version = "1.0.44" # remember to update html_root_url 4 | authors = ["Erick Tryzelaar ", "David Tolnay "] 5 | license = "MIT OR Apache-2.0" 6 | description = "A JSON serialization file format" 7 | repository = "https://github.com/serde-rs/json" 8 | documentation = "http://docs.serde.rs/serde_json/" 9 | keywords = ["json", "serde", "serialization"] 10 | categories = ["encoding"] 11 | readme = "README.md" 12 | include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] 13 | 14 | [badges] 15 | travis-ci = { repository = "serde-rs/json" } 16 | appveyor = { repository = "serde-rs/json" } 17 | 18 | [dependencies] 19 | serde = "1.0.60" 20 | indexmap = { version = "1.2", optional = true } 21 | itoa = "0.4.3" 22 | ryu = "1.0" 23 | 24 | [dev-dependencies] 25 | automod = "0.1" 26 | rustversion = "1.0" 27 | serde_bytes = "0.11" 28 | serde_derive = "1.0" 29 | serde_stacker = "0.1" 30 | trybuild = "1.0" 31 | 32 | [workspace] 33 | members = ["tests/crate"] 34 | 35 | [package.metadata.docs.rs] 36 | features = ["raw_value", "unbounded_depth"] 37 | 38 | [package.metadata.playground] 39 | features = ["raw_value"] 40 | 41 | 42 | ### FEATURES ################################################################# 43 | 44 | [features] 45 | default = [] 46 | 47 | # Use a different representation for the map type of serde_json::Value. 48 | # This allows data to be read into a Value and written back to a JSON string 49 | # while preserving the order of map keys in the input. 50 | preserve_order = ["indexmap"] 51 | 52 | # Use an arbitrary precision number representation for serde_json::Number. This 53 | # allows JSON numbers of arbitrary size/precision to be read into a Number and 54 | # written back to a JSON string without loss of precision. 55 | arbitrary_precision = [] 56 | 57 | # Provide a RawValue type that can hold unprocessed JSON during deserialization. 58 | raw_value = [] 59 | 60 | # Provide a method disable_recursion_limit to parse arbitrarily deep JSON 61 | # structures without any consideration for overflowing the stack. When using 62 | # this feature, you will want to provide some other way to protect against stack 63 | # overflows, such as by wrapping your Deserializer in the dynamically growing 64 | # stack adapter provided by the serde_stacker crate. Additionally you will need 65 | # to be careful around other recursive operations on the parsed result which may 66 | # overflow the stack after deserialization has completed, including, but not 67 | # limited to, Display and Debug and Drop impls. 68 | unbounded_depth = [] 69 | -------------------------------------------------------------------------------- /tests/stream.rs: -------------------------------------------------------------------------------- 1 | #![cfg(not(feature = "preserve_order"))] 2 | 3 | extern crate serde; 4 | 5 | #[macro_use] 6 | extern crate serde_json; 7 | 8 | use serde_json::{Deserializer, Value}; 9 | 10 | // Rustfmt issue https://github.com/rust-lang-nursery/rustfmt/issues/2740 11 | #[cfg_attr(rustfmt, rustfmt_skip)] 12 | macro_rules! test_stream { 13 | ($data:expr, $ty:ty, |$stream:ident| $test:block) => { 14 | { 15 | let de = Deserializer::from_str($data); 16 | let mut $stream = de.into_iter::<$ty>(); 17 | assert_eq!($stream.byte_offset(), 0); 18 | $test 19 | } 20 | { 21 | let de = Deserializer::from_slice($data.as_bytes()); 22 | let mut $stream = de.into_iter::<$ty>(); 23 | assert_eq!($stream.byte_offset(), 0); 24 | $test 25 | } 26 | { 27 | let mut bytes = $data.as_bytes(); 28 | let de = Deserializer::from_reader(&mut bytes); 29 | let mut $stream = de.into_iter::<$ty>(); 30 | assert_eq!($stream.byte_offset(), 0); 31 | $test 32 | } 33 | }; 34 | } 35 | 36 | #[test] 37 | fn test_json_stream_newlines() { 38 | let data = "{\"x\":39} {\"x\":40}{\"x\":41}\n{\"x\":42}"; 39 | 40 | test_stream!(data, Value, |stream| { 41 | assert_eq!(stream.next().unwrap().unwrap()["x"], 39); 42 | assert_eq!(stream.byte_offset(), 8); 43 | 44 | assert_eq!(stream.next().unwrap().unwrap()["x"], 40); 45 | assert_eq!(stream.byte_offset(), 17); 46 | 47 | assert_eq!(stream.next().unwrap().unwrap()["x"], 41); 48 | assert_eq!(stream.byte_offset(), 25); 49 | 50 | assert_eq!(stream.next().unwrap().unwrap()["x"], 42); 51 | assert_eq!(stream.byte_offset(), 34); 52 | 53 | assert!(stream.next().is_none()); 54 | assert_eq!(stream.byte_offset(), 34); 55 | }); 56 | } 57 | 58 | #[test] 59 | fn test_json_stream_trailing_whitespaces() { 60 | let data = "{\"x\":42} \t\n"; 61 | 62 | test_stream!(data, Value, |stream| { 63 | assert_eq!(stream.next().unwrap().unwrap()["x"], 42); 64 | assert_eq!(stream.byte_offset(), 8); 65 | 66 | assert!(stream.next().is_none()); 67 | assert_eq!(stream.byte_offset(), 11); 68 | }); 69 | } 70 | 71 | #[test] 72 | fn test_json_stream_truncated() { 73 | let data = "{\"x\":40}\n{\"x\":"; 74 | 75 | test_stream!(data, Value, |stream| { 76 | assert_eq!(stream.next().unwrap().unwrap()["x"], 40); 77 | assert_eq!(stream.byte_offset(), 8); 78 | 79 | assert!(stream.next().unwrap().unwrap_err().is_eof()); 80 | assert_eq!(stream.byte_offset(), 9); 81 | }); 82 | } 83 | 84 | #[test] 85 | fn test_json_stream_truncated_decimal() { 86 | let data = "{\"x\":4."; 87 | 88 | test_stream!(data, Value, |stream| { 89 | assert!(stream.next().unwrap().unwrap_err().is_eof()); 90 | assert_eq!(stream.byte_offset(), 0); 91 | }); 92 | } 93 | 94 | #[test] 95 | fn test_json_stream_truncated_negative() { 96 | let data = "{\"x\":-"; 97 | 98 | test_stream!(data, Value, |stream| { 99 | assert!(stream.next().unwrap().unwrap_err().is_eof()); 100 | assert_eq!(stream.byte_offset(), 0); 101 | }); 102 | } 103 | 104 | #[test] 105 | fn test_json_stream_truncated_exponent() { 106 | let data = "{\"x\":4e"; 107 | 108 | test_stream!(data, Value, |stream| { 109 | assert!(stream.next().unwrap().unwrap_err().is_eof()); 110 | assert_eq!(stream.byte_offset(), 0); 111 | }); 112 | } 113 | 114 | #[test] 115 | fn test_json_stream_empty() { 116 | let data = ""; 117 | 118 | test_stream!(data, Value, |stream| { 119 | assert!(stream.next().is_none()); 120 | assert_eq!(stream.byte_offset(), 0); 121 | }); 122 | } 123 | 124 | #[test] 125 | fn test_json_stream_primitive() { 126 | let data = "{} true{}1[]\nfalse\"hey\"2 "; 127 | 128 | test_stream!(data, Value, |stream| { 129 | assert_eq!(stream.next().unwrap().unwrap(), json!({})); 130 | assert_eq!(stream.byte_offset(), 2); 131 | 132 | assert_eq!(stream.next().unwrap().unwrap(), true); 133 | assert_eq!(stream.byte_offset(), 7); 134 | 135 | assert_eq!(stream.next().unwrap().unwrap(), json!({})); 136 | assert_eq!(stream.byte_offset(), 9); 137 | 138 | assert_eq!(stream.next().unwrap().unwrap(), 1); 139 | assert_eq!(stream.byte_offset(), 10); 140 | 141 | assert_eq!(stream.next().unwrap().unwrap(), json!([])); 142 | assert_eq!(stream.byte_offset(), 12); 143 | 144 | assert_eq!(stream.next().unwrap().unwrap(), false); 145 | assert_eq!(stream.byte_offset(), 18); 146 | 147 | assert_eq!(stream.next().unwrap().unwrap(), "hey"); 148 | assert_eq!(stream.byte_offset(), 23); 149 | 150 | assert_eq!(stream.next().unwrap().unwrap(), 2); 151 | assert_eq!(stream.byte_offset(), 24); 152 | 153 | assert!(stream.next().is_none()); 154 | assert_eq!(stream.byte_offset(), 25); 155 | }); 156 | } 157 | 158 | #[test] 159 | fn test_json_stream_invalid_literal() { 160 | let data = "truefalse"; 161 | 162 | test_stream!(data, Value, |stream| { 163 | let second = stream.next().unwrap().unwrap_err(); 164 | assert_eq!(second.to_string(), "trailing characters at line 1 column 5"); 165 | }); 166 | } 167 | 168 | #[test] 169 | fn test_json_stream_invalid_number() { 170 | let data = "1true"; 171 | 172 | test_stream!(data, Value, |stream| { 173 | let second = stream.next().unwrap().unwrap_err(); 174 | assert_eq!(second.to_string(), "trailing characters at line 1 column 2"); 175 | }); 176 | } 177 | -------------------------------------------------------------------------------- /src/value/from.rs: -------------------------------------------------------------------------------- 1 | use std::borrow::Cow; 2 | 3 | use super::Value; 4 | use map::Map; 5 | use number::Number; 6 | 7 | macro_rules! from_integer { 8 | ($($ty:ident)*) => { 9 | $( 10 | impl From<$ty> for Value { 11 | fn from(n: $ty) -> Self { 12 | Value::Number(n.into()) 13 | } 14 | } 15 | )* 16 | }; 17 | } 18 | 19 | from_integer! { 20 | i8 i16 i32 i64 isize 21 | u8 u16 u32 u64 usize 22 | } 23 | 24 | #[cfg(feature = "arbitrary_precision")] 25 | serde_if_integer128! { 26 | from_integer! { 27 | i128 u128 28 | } 29 | } 30 | 31 | impl From for Value { 32 | /// Convert 32-bit floating point number to `Value` 33 | /// 34 | /// # Examples 35 | /// 36 | /// ```edition2018 37 | /// use serde_json::Value; 38 | /// 39 | /// let f: f32 = 13.37; 40 | /// let x: Value = f.into(); 41 | /// ``` 42 | fn from(f: f32) -> Self { 43 | From::from(f as f64) 44 | } 45 | } 46 | 47 | impl From for Value { 48 | /// Convert 64-bit floating point number to `Value` 49 | /// 50 | /// # Examples 51 | /// 52 | /// ```edition2018 53 | /// use serde_json::Value; 54 | /// 55 | /// let f: f64 = 13.37; 56 | /// let x: Value = f.into(); 57 | /// ``` 58 | fn from(f: f64) -> Self { 59 | Number::from_f64(f).map_or(Value::Null, Value::Number) 60 | } 61 | } 62 | 63 | impl From for Value { 64 | /// Convert boolean to `Value` 65 | /// 66 | /// # Examples 67 | /// 68 | /// ```edition2018 69 | /// use serde_json::Value; 70 | /// 71 | /// let b = false; 72 | /// let x: Value = b.into(); 73 | /// ``` 74 | fn from(f: bool) -> Self { 75 | Value::Bool(f) 76 | } 77 | } 78 | 79 | impl From for Value { 80 | /// Convert `String` to `Value` 81 | /// 82 | /// # Examples 83 | /// 84 | /// ```edition2018 85 | /// use serde_json::Value; 86 | /// 87 | /// let s: String = "lorem".to_string(); 88 | /// let x: Value = s.into(); 89 | /// ``` 90 | fn from(f: String) -> Self { 91 | Value::String(f) 92 | } 93 | } 94 | 95 | impl<'a> From<&'a str> for Value { 96 | /// Convert string slice to `Value` 97 | /// 98 | /// # Examples 99 | /// 100 | /// ```edition2018 101 | /// use serde_json::Value; 102 | /// 103 | /// let s: &str = "lorem"; 104 | /// let x: Value = s.into(); 105 | /// ``` 106 | fn from(f: &str) -> Self { 107 | Value::String(f.to_string()) 108 | } 109 | } 110 | 111 | impl<'a> From> for Value { 112 | /// Convert copy-on-write string to `Value` 113 | /// 114 | /// # Examples 115 | /// 116 | /// ```edition2018 117 | /// use serde_json::Value; 118 | /// use std::borrow::Cow; 119 | /// 120 | /// let s: Cow = Cow::Borrowed("lorem"); 121 | /// let x: Value = s.into(); 122 | /// ``` 123 | /// 124 | /// ```edition2018 125 | /// use serde_json::Value; 126 | /// use std::borrow::Cow; 127 | /// 128 | /// let s: Cow = Cow::Owned("lorem".to_string()); 129 | /// let x: Value = s.into(); 130 | /// ``` 131 | fn from(f: Cow<'a, str>) -> Self { 132 | Value::String(f.into_owned()) 133 | } 134 | } 135 | 136 | impl From> for Value { 137 | /// Convert map (with string keys) to `Value` 138 | /// 139 | /// # Examples 140 | /// 141 | /// ```edition2018 142 | /// use serde_json::{Map, Value}; 143 | /// 144 | /// let mut m = Map::new(); 145 | /// m.insert("Lorem".to_string(), "ipsum".into()); 146 | /// let x: Value = m.into(); 147 | /// ``` 148 | fn from(f: Map) -> Self { 149 | Value::Object(f) 150 | } 151 | } 152 | 153 | impl> From> for Value { 154 | /// Convert a `Vec` to `Value` 155 | /// 156 | /// # Examples 157 | /// 158 | /// ```edition2018 159 | /// use serde_json::Value; 160 | /// 161 | /// let v = vec!["lorem", "ipsum", "dolor"]; 162 | /// let x: Value = v.into(); 163 | /// ``` 164 | fn from(f: Vec) -> Self { 165 | Value::Array(f.into_iter().map(Into::into).collect()) 166 | } 167 | } 168 | 169 | impl<'a, T: Clone + Into> From<&'a [T]> for Value { 170 | /// Convert a slice to `Value` 171 | /// 172 | /// # Examples 173 | /// 174 | /// ```edition2018 175 | /// use serde_json::Value; 176 | /// 177 | /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; 178 | /// let x: Value = v.into(); 179 | /// ``` 180 | fn from(f: &'a [T]) -> Self { 181 | Value::Array(f.iter().cloned().map(Into::into).collect()) 182 | } 183 | } 184 | 185 | impl> ::std::iter::FromIterator for Value { 186 | /// Convert an iteratable type to a `Value` 187 | /// 188 | /// # Examples 189 | /// 190 | /// ```edition2018 191 | /// use serde_json::Value; 192 | /// 193 | /// let v = std::iter::repeat(42).take(5); 194 | /// let x: Value = v.collect(); 195 | /// ``` 196 | /// 197 | /// ```edition2018 198 | /// use serde_json::Value; 199 | /// 200 | /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; 201 | /// let x: Value = v.into_iter().collect(); 202 | /// ``` 203 | /// 204 | /// ```edition2018 205 | /// use std::iter::FromIterator; 206 | /// use serde_json::Value; 207 | /// 208 | /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); 209 | /// ``` 210 | fn from_iter>(iter: I) -> Self { 211 | Value::Array(iter.into_iter().map(Into::into).collect()) 212 | } 213 | } 214 | 215 | impl From<()> for Value { 216 | /// Convert `()` to `Value` 217 | /// 218 | /// # Examples 219 | /// 220 | /// ```edition2018 221 | /// use serde_json::Value; 222 | /// 223 | /// let u = (); 224 | /// let x: Value = u.into(); 225 | /// ``` 226 | fn from((): ()) -> Self { 227 | Value::Null 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /src/value/index.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::ops; 3 | 4 | use super::Value; 5 | use map::Map; 6 | 7 | /// A type that can be used to index into a `serde_json::Value`. 8 | /// 9 | /// The [`get`] and [`get_mut`] methods of `Value` accept any type that 10 | /// implements `Index`, as does the [square-bracket indexing operator]. This 11 | /// trait is implemented for strings which are used as the index into a JSON 12 | /// map, and for `usize` which is used as the index into a JSON array. 13 | /// 14 | /// [`get`]: ../enum.Value.html#method.get 15 | /// [`get_mut`]: ../enum.Value.html#method.get_mut 16 | /// [square-bracket indexing operator]: ../enum.Value.html#impl-Index%3CI%3E 17 | /// 18 | /// This trait is sealed and cannot be implemented for types outside of 19 | /// `serde_json`. 20 | /// 21 | /// # Examples 22 | /// 23 | /// ```edition2018 24 | /// # use serde_json::json; 25 | /// # 26 | /// let data = json!({ "inner": [1, 2, 3] }); 27 | /// 28 | /// // Data is a JSON map so it can be indexed with a string. 29 | /// let inner = &data["inner"]; 30 | /// 31 | /// // Inner is a JSON array so it can be indexed with an integer. 32 | /// let first = &inner[0]; 33 | /// 34 | /// assert_eq!(first, 1); 35 | /// ``` 36 | pub trait Index: private::Sealed { 37 | /// Return None if the key is not already in the array or object. 38 | #[doc(hidden)] 39 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>; 40 | 41 | /// Return None if the key is not already in the array or object. 42 | #[doc(hidden)] 43 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; 44 | 45 | /// Panic if array index out of bounds. If key is not already in the object, 46 | /// insert it with a value of null. Panic if Value is a type that cannot be 47 | /// indexed into, except if Value is null then it can be treated as an empty 48 | /// object. 49 | #[doc(hidden)] 50 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value; 51 | } 52 | 53 | impl Index for usize { 54 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 55 | match *v { 56 | Value::Array(ref vec) => vec.get(*self), 57 | _ => None, 58 | } 59 | } 60 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 61 | match *v { 62 | Value::Array(ref mut vec) => vec.get_mut(*self), 63 | _ => None, 64 | } 65 | } 66 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 67 | match *v { 68 | Value::Array(ref mut vec) => { 69 | let len = vec.len(); 70 | vec.get_mut(*self).unwrap_or_else(|| { 71 | panic!( 72 | "cannot access index {} of JSON array of length {}", 73 | self, len 74 | ) 75 | }) 76 | } 77 | _ => panic!("cannot access index {} of JSON {}", self, Type(v)), 78 | } 79 | } 80 | } 81 | 82 | impl Index for str { 83 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 84 | match *v { 85 | Value::Object(ref map) => map.get(self), 86 | _ => None, 87 | } 88 | } 89 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 90 | match *v { 91 | Value::Object(ref mut map) => map.get_mut(self), 92 | _ => None, 93 | } 94 | } 95 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 96 | if let Value::Null = *v { 97 | *v = Value::Object(Map::new()); 98 | } 99 | match *v { 100 | Value::Object(ref mut map) => map.entry(self.to_owned()).or_insert(Value::Null), 101 | _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), 102 | } 103 | } 104 | } 105 | 106 | impl Index for String { 107 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 108 | self[..].index_into(v) 109 | } 110 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 111 | self[..].index_into_mut(v) 112 | } 113 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 114 | self[..].index_or_insert(v) 115 | } 116 | } 117 | 118 | impl<'a, T: ?Sized> Index for &'a T 119 | where 120 | T: Index, 121 | { 122 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 123 | (**self).index_into(v) 124 | } 125 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 126 | (**self).index_into_mut(v) 127 | } 128 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 129 | (**self).index_or_insert(v) 130 | } 131 | } 132 | 133 | // Prevent users from implementing the Index trait. 134 | mod private { 135 | pub trait Sealed {} 136 | impl Sealed for usize {} 137 | impl Sealed for str {} 138 | impl Sealed for String {} 139 | impl<'a, T: ?Sized> Sealed for &'a T where T: Sealed {} 140 | } 141 | 142 | /// Used in panic messages. 143 | struct Type<'a>(&'a Value); 144 | 145 | impl<'a> fmt::Display for Type<'a> { 146 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 147 | match *self.0 { 148 | Value::Null => formatter.write_str("null"), 149 | Value::Bool(_) => formatter.write_str("boolean"), 150 | Value::Number(_) => formatter.write_str("number"), 151 | Value::String(_) => formatter.write_str("string"), 152 | Value::Array(_) => formatter.write_str("array"), 153 | Value::Object(_) => formatter.write_str("object"), 154 | } 155 | } 156 | } 157 | 158 | // The usual semantics of Index is to panic on invalid indexing. 159 | // 160 | // That said, the usual semantics are for things like Vec and BTreeMap which 161 | // have different use cases than Value. If you are working with a Vec, you know 162 | // that you are working with a Vec and you can get the len of the Vec and make 163 | // sure your indices are within bounds. The Value use cases are more 164 | // loosey-goosey. You got some JSON from an endpoint and you want to pull values 165 | // out of it. Outside of this Index impl, you already have the option of using 166 | // value.as_array() and working with the Vec directly, or matching on 167 | // Value::Array and getting the Vec directly. The Index impl means you can skip 168 | // that and index directly into the thing using a concise syntax. You don't have 169 | // to check the type, you don't have to check the len, it is all about what you 170 | // expect the Value to look like. 171 | // 172 | // Basically the use cases that would be well served by panicking here are 173 | // better served by using one of the other approaches: get and get_mut, 174 | // as_array, or match. The value of this impl is that it adds a way of working 175 | // with Value that is not well served by the existing approaches: concise and 176 | // careless and sometimes that is exactly what you want. 177 | impl ops::Index for Value 178 | where 179 | I: Index, 180 | { 181 | type Output = Value; 182 | 183 | /// Index into a `serde_json::Value` using the syntax `value[0]` or 184 | /// `value["k"]`. 185 | /// 186 | /// Returns `Value::Null` if the type of `self` does not match the type of 187 | /// the index, for example if the index is a string and `self` is an array 188 | /// or a number. Also returns `Value::Null` if the given key does not exist 189 | /// in the map or the given index is not within the bounds of the array. 190 | /// 191 | /// For retrieving deeply nested values, you should have a look at the 192 | /// `Value::pointer` method. 193 | /// 194 | /// # Examples 195 | /// 196 | /// ```edition2018 197 | /// # use serde_json::json; 198 | /// # 199 | /// let data = json!({ 200 | /// "x": { 201 | /// "y": ["z", "zz"] 202 | /// } 203 | /// }); 204 | /// 205 | /// assert_eq!(data["x"]["y"], json!(["z", "zz"])); 206 | /// assert_eq!(data["x"]["y"][0], json!("z")); 207 | /// 208 | /// assert_eq!(data["a"], json!(null)); // returns null for undefined values 209 | /// assert_eq!(data["a"]["b"], json!(null)); // does not panic 210 | /// ``` 211 | fn index(&self, index: I) -> &Value { 212 | static NULL: Value = Value::Null; 213 | index.index_into(self).unwrap_or(&NULL) 214 | } 215 | } 216 | 217 | impl ops::IndexMut for Value 218 | where 219 | I: Index, 220 | { 221 | /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or 222 | /// `value["k"] = ...`. 223 | /// 224 | /// If the index is a number, the value must be an array of length bigger 225 | /// than the index. Indexing into a value that is not an array or an array 226 | /// that is too small will panic. 227 | /// 228 | /// If the index is a string, the value must be an object or null which is 229 | /// treated like an empty object. If the key is not already present in the 230 | /// object, it will be inserted with a value of null. Indexing into a value 231 | /// that is neither an object nor null will panic. 232 | /// 233 | /// # Examples 234 | /// 235 | /// ```edition2018 236 | /// # use serde_json::json; 237 | /// # 238 | /// let mut data = json!({ "x": 0 }); 239 | /// 240 | /// // replace an existing key 241 | /// data["x"] = json!(1); 242 | /// 243 | /// // insert a new key 244 | /// data["y"] = json!([false, false, false]); 245 | /// 246 | /// // replace an array value 247 | /// data["y"][0] = json!(true); 248 | /// 249 | /// // inserted a deeply nested key 250 | /// data["a"]["b"]["c"]["d"] = json!(true); 251 | /// 252 | /// println!("{}", data); 253 | /// ``` 254 | fn index_mut(&mut self, index: I) -> &mut Value { 255 | index.index_or_insert(self) 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /src/macros.rs: -------------------------------------------------------------------------------- 1 | /// Construct a `serde_json::Value` from a JSON literal. 2 | /// 3 | /// ```edition2018 4 | /// # use serde_json::json; 5 | /// # 6 | /// let value = json!({ 7 | /// "code": 200, 8 | /// "success": true, 9 | /// "payload": { 10 | /// "features": [ 11 | /// "serde", 12 | /// "json" 13 | /// ] 14 | /// } 15 | /// }); 16 | /// ``` 17 | /// 18 | /// Variables or expressions can be interpolated into the JSON literal. Any type 19 | /// interpolated into an array element or object value must implement Serde's 20 | /// `Serialize` trait, while any type interpolated into a object key must 21 | /// implement `Into`. If the `Serialize` implementation of the 22 | /// interpolated type decides to fail, or if the interpolated type contains a 23 | /// map with non-string keys, the `json!` macro will panic. 24 | /// 25 | /// ```edition2018 26 | /// # use serde_json::json; 27 | /// # 28 | /// let code = 200; 29 | /// let features = vec!["serde", "json"]; 30 | /// 31 | /// let value = json!({ 32 | /// "code": code, 33 | /// "success": code == 200, 34 | /// "payload": { 35 | /// features[0]: features[1] 36 | /// } 37 | /// }); 38 | /// ``` 39 | /// 40 | /// Trailing commas are allowed inside both arrays and objects. 41 | /// 42 | /// ```edition2018 43 | /// # use serde_json::json; 44 | /// # 45 | /// let value = json!([ 46 | /// "notice", 47 | /// "the", 48 | /// "trailing", 49 | /// "comma -->", 50 | /// ]); 51 | /// ``` 52 | #[macro_export(local_inner_macros)] 53 | macro_rules! json { 54 | // Hide distracting implementation details from the generated rustdoc. 55 | ($($json:tt)+) => { 56 | json_internal!($($json)+) 57 | }; 58 | } 59 | 60 | // Rocket relies on this because they export their own `json!` with a different 61 | // doc comment than ours, and various Rust bugs prevent them from calling our 62 | // `json!` from their `json!` so they call `json_internal!` directly. Check with 63 | // @SergioBenitez before making breaking changes to this macro. 64 | // 65 | // Changes are fine as long as `json_internal!` does not call any new helper 66 | // macros and can still be invoked as `json_internal!($($json)+)`. 67 | #[macro_export(local_inner_macros)] 68 | #[doc(hidden)] 69 | macro_rules! json_internal { 70 | ////////////////////////////////////////////////////////////////////////// 71 | // TT muncher for parsing the inside of an array [...]. Produces a vec![...] 72 | // of the elements. 73 | // 74 | // Must be invoked as: json_internal!(@array [] $($tt)*) 75 | ////////////////////////////////////////////////////////////////////////// 76 | 77 | // Done with trailing comma. 78 | (@array [$($elems:expr,)*]) => { 79 | json_internal_vec![$($elems,)*] 80 | }; 81 | 82 | // Done without trailing comma. 83 | (@array [$($elems:expr),*]) => { 84 | json_internal_vec![$($elems),*] 85 | }; 86 | 87 | // Next element is `null`. 88 | (@array [$($elems:expr,)*] null $($rest:tt)*) => { 89 | json_internal!(@array [$($elems,)* json_internal!(null)] $($rest)*) 90 | }; 91 | 92 | // Next element is `true`. 93 | (@array [$($elems:expr,)*] true $($rest:tt)*) => { 94 | json_internal!(@array [$($elems,)* json_internal!(true)] $($rest)*) 95 | }; 96 | 97 | // Next element is `false`. 98 | (@array [$($elems:expr,)*] false $($rest:tt)*) => { 99 | json_internal!(@array [$($elems,)* json_internal!(false)] $($rest)*) 100 | }; 101 | 102 | // Next element is an array. 103 | (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { 104 | json_internal!(@array [$($elems,)* json_internal!([$($array)*])] $($rest)*) 105 | }; 106 | 107 | // Next element is a map. 108 | (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { 109 | json_internal!(@array [$($elems,)* json_internal!({$($map)*})] $($rest)*) 110 | }; 111 | 112 | // Next element is an expression followed by comma. 113 | (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { 114 | json_internal!(@array [$($elems,)* json_internal!($next),] $($rest)*) 115 | }; 116 | 117 | // Last element is an expression with no trailing comma. 118 | (@array [$($elems:expr,)*] $last:expr) => { 119 | json_internal!(@array [$($elems,)* json_internal!($last)]) 120 | }; 121 | 122 | // Comma after the most recent element. 123 | (@array [$($elems:expr),*] , $($rest:tt)*) => { 124 | json_internal!(@array [$($elems,)*] $($rest)*) 125 | }; 126 | 127 | // Unexpected token after most recent element. 128 | (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { 129 | json_unexpected!($unexpected) 130 | }; 131 | 132 | ////////////////////////////////////////////////////////////////////////// 133 | // TT muncher for parsing the inside of an object {...}. Each entry is 134 | // inserted into the given map variable. 135 | // 136 | // Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*)) 137 | // 138 | // We require two copies of the input tokens so that we can match on one 139 | // copy and trigger errors on the other copy. 140 | ////////////////////////////////////////////////////////////////////////// 141 | 142 | // Done. 143 | (@object $object:ident () () ()) => {}; 144 | 145 | // Insert the current entry followed by trailing comma. 146 | (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { 147 | let _ = $object.insert(($($key)+).into(), $value); 148 | json_internal!(@object $object () ($($rest)*) ($($rest)*)); 149 | }; 150 | 151 | // Current entry followed by unexpected token. 152 | (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { 153 | json_unexpected!($unexpected); 154 | }; 155 | 156 | // Insert the last entry without trailing comma. 157 | (@object $object:ident [$($key:tt)+] ($value:expr)) => { 158 | let _ = $object.insert(($($key)+).into(), $value); 159 | }; 160 | 161 | // Next value is `null`. 162 | (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { 163 | json_internal!(@object $object [$($key)+] (json_internal!(null)) $($rest)*); 164 | }; 165 | 166 | // Next value is `true`. 167 | (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => { 168 | json_internal!(@object $object [$($key)+] (json_internal!(true)) $($rest)*); 169 | }; 170 | 171 | // Next value is `false`. 172 | (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => { 173 | json_internal!(@object $object [$($key)+] (json_internal!(false)) $($rest)*); 174 | }; 175 | 176 | // Next value is an array. 177 | (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { 178 | json_internal!(@object $object [$($key)+] (json_internal!([$($array)*])) $($rest)*); 179 | }; 180 | 181 | // Next value is a map. 182 | (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { 183 | json_internal!(@object $object [$($key)+] (json_internal!({$($map)*})) $($rest)*); 184 | }; 185 | 186 | // Next value is an expression followed by comma. 187 | (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { 188 | json_internal!(@object $object [$($key)+] (json_internal!($value)) , $($rest)*); 189 | }; 190 | 191 | // Last value is an expression with no trailing comma. 192 | (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { 193 | json_internal!(@object $object [$($key)+] (json_internal!($value))); 194 | }; 195 | 196 | // Missing value for last entry. Trigger a reasonable error message. 197 | (@object $object:ident ($($key:tt)+) (:) $copy:tt) => { 198 | // "unexpected end of macro invocation" 199 | json_internal!(); 200 | }; 201 | 202 | // Missing colon and value for last entry. Trigger a reasonable error 203 | // message. 204 | (@object $object:ident ($($key:tt)+) () $copy:tt) => { 205 | // "unexpected end of macro invocation" 206 | json_internal!(); 207 | }; 208 | 209 | // Misplaced colon. Trigger a reasonable error message. 210 | (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { 211 | // Takes no arguments so "no rules expected the token `:`". 212 | json_unexpected!($colon); 213 | }; 214 | 215 | // Found a comma inside a key. Trigger a reasonable error message. 216 | (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { 217 | // Takes no arguments so "no rules expected the token `,`". 218 | json_unexpected!($comma); 219 | }; 220 | 221 | // Key is fully parenthesized. This avoids clippy double_parens false 222 | // positives because the parenthesization may be necessary here. 223 | (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { 224 | json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*)); 225 | }; 226 | 227 | // Munch a token into the current key. 228 | (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { 229 | json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*)); 230 | }; 231 | 232 | ////////////////////////////////////////////////////////////////////////// 233 | // The main implementation. 234 | // 235 | // Must be invoked as: json_internal!($($json)+) 236 | ////////////////////////////////////////////////////////////////////////// 237 | 238 | (null) => { 239 | $crate::Value::Null 240 | }; 241 | 242 | (true) => { 243 | $crate::Value::Bool(true) 244 | }; 245 | 246 | (false) => { 247 | $crate::Value::Bool(false) 248 | }; 249 | 250 | ([]) => { 251 | $crate::Value::Array(json_internal_vec![]) 252 | }; 253 | 254 | ([ $($tt:tt)+ ]) => { 255 | $crate::Value::Array(json_internal!(@array [] $($tt)+)) 256 | }; 257 | 258 | ({}) => { 259 | $crate::Value::Object($crate::Map::new()) 260 | }; 261 | 262 | ({ $($tt:tt)+ }) => { 263 | $crate::Value::Object({ 264 | let mut object = $crate::Map::new(); 265 | json_internal!(@object object () ($($tt)+) ($($tt)+)); 266 | object 267 | }) 268 | }; 269 | 270 | // Any Serialize type: numbers, strings, struct literals, variables etc. 271 | // Must be below every other rule. 272 | ($other:expr) => { 273 | $crate::to_value(&$other).unwrap() 274 | }; 275 | } 276 | 277 | // The json_internal macro above cannot invoke vec directly because it uses 278 | // local_inner_macros. A vec invocation there would resolve to $crate::vec. 279 | // Instead invoke vec here outside of local_inner_macros. 280 | #[macro_export] 281 | #[doc(hidden)] 282 | macro_rules! json_internal_vec { 283 | ($($content:tt)*) => { 284 | vec![$($content)*] 285 | }; 286 | } 287 | 288 | #[macro_export] 289 | #[doc(hidden)] 290 | macro_rules! json_unexpected { 291 | () => {}; 292 | } 293 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serde JSON   [![Build Status]][travis] [![Latest Version]][crates.io] [![Rustc Version 1.15+]][rustc] 2 | 3 | [Build Status]: https://api.travis-ci.org/serde-rs/json.svg?branch=master 4 | [travis]: https://travis-ci.org/serde-rs/json 5 | [Latest Version]: https://img.shields.io/crates/v/serde_json.svg 6 | [crates.io]: https://crates.io/crates/serde\_json 7 | [Rustc Version 1.15+]: https://img.shields.io/badge/rustc-1.15+-lightgray.svg 8 | [rustc]: https://blog.rust-lang.org/2017/02/02/Rust-1.15.html 9 | 10 | **Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** 11 | 12 | --- 13 | 14 | ```toml 15 | [dependencies] 16 | serde_json = "1.0" 17 | ``` 18 | 19 | You may be looking for: 20 | 21 | - [JSON API documentation](https://docs.serde.rs/serde_json/) 22 | - [Serde API documentation](https://docs.serde.rs/serde/) 23 | - [Detailed documentation about Serde](https://serde.rs/) 24 | - [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html) 25 | - [Release notes](https://github.com/serde-rs/json/releases) 26 | 27 | JSON is a ubiquitous open-standard format that uses human-readable text to 28 | transmit data objects consisting of key-value pairs. 29 | 30 | ```json 31 | { 32 | "name": "John Doe", 33 | "age": 43, 34 | "address": { 35 | "street": "10 Downing Street", 36 | "city": "London" 37 | }, 38 | "phones": [ 39 | "+44 1234567", 40 | "+44 2345678" 41 | ] 42 | } 43 | ``` 44 | 45 | There are three common ways that you might find yourself needing to work 46 | with JSON data in Rust. 47 | 48 | - **As text data.** An unprocessed string of JSON data that you receive on 49 | an HTTP endpoint, read from a file, or prepare to send to a remote 50 | server. 51 | - **As an untyped or loosely typed representation.** Maybe you want to 52 | check that some JSON data is valid before passing it on, but without 53 | knowing the structure of what it contains. Or you want to do very basic 54 | manipulations like insert a key in a particular spot. 55 | - **As a strongly typed Rust data structure.** When you expect all or most 56 | of your data to conform to a particular structure and want to get real 57 | work done without JSON's loosey-goosey nature tripping you up. 58 | 59 | Serde JSON provides efficient, flexible, safe ways of converting data 60 | between each of these representations. 61 | 62 | ## Operating on untyped JSON values 63 | 64 | Any valid JSON data can be manipulated in the following recursive enum 65 | representation. This data structure is [`serde_json::Value`][value]. 66 | 67 | ```rust 68 | enum Value { 69 | Null, 70 | Bool(bool), 71 | Number(Number), 72 | String(String), 73 | Array(Vec), 74 | Object(Map), 75 | } 76 | ``` 77 | 78 | A string of JSON data can be parsed into a `serde_json::Value` by the 79 | [`serde_json::from_str`][from_str] function. There is also 80 | [`from_slice`][from_slice] for parsing from a byte slice &[u8] and 81 | [`from_reader`][from_reader] for parsing from any `io::Read` like a File or 82 | a TCP stream. 83 | 84 | 85 | 86 | 87 | 88 | ```rust 89 | use serde_json::{Result, Value}; 90 | 91 | fn untyped_example() -> Result<()> { 92 | // Some JSON input data as a &str. Maybe this comes from the user. 93 | let data = r#" 94 | { 95 | "name": "John Doe", 96 | "age": 43, 97 | "phones": [ 98 | "+44 1234567", 99 | "+44 2345678" 100 | ] 101 | }"#; 102 | 103 | // Parse the string of data into serde_json::Value. 104 | let v: Value = serde_json::from_str(data)?; 105 | 106 | // Access parts of the data by indexing with square brackets. 107 | println!("Please call {} at the number {}", v["name"], v["phones"][0]); 108 | 109 | Ok(()) 110 | } 111 | ``` 112 | 113 | The result of square bracket indexing like `v["name"]` is a borrow of the data 114 | at that index, so the type is `&Value`. A JSON map can be indexed with string 115 | keys, while a JSON array can be indexed with integer keys. If the type of the 116 | data is not right for the type with which it is being indexed, or if a map does 117 | not contain the key being indexed, or if the index into a vector is out of 118 | bounds, the returned element is `Value::Null`. 119 | 120 | When a `Value` is printed, it is printed as a JSON string. So in the code above, 121 | the output looks like `Please call "John Doe" at the number "+44 1234567"`. The 122 | quotation marks appear because `v["name"]` is a `&Value` containing a JSON 123 | string and its JSON representation is `"John Doe"`. Printing as a plain string 124 | without quotation marks involves converting from a JSON string to a Rust string 125 | with [`as_str()`] or avoiding the use of `Value` as described in the following 126 | section. 127 | 128 | [`as_str()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.as_str 129 | 130 | The `Value` representation is sufficient for very basic tasks but can be tedious 131 | to work with for anything more significant. Error handling is verbose to 132 | implement correctly, for example imagine trying to detect the presence of 133 | unrecognized fields in the input data. The compiler is powerless to help you 134 | when you make a mistake, for example imagine typoing `v["name"]` as `v["nmae"]` 135 | in one of the dozens of places it is used in your code. 136 | 137 | ## Parsing JSON as strongly typed data structures 138 | 139 | Serde provides a powerful way of mapping JSON data into Rust data structures 140 | largely automatically. 141 | 142 | 143 | 144 | 145 | 146 | ```rust 147 | use serde::{Deserialize, Serialize}; 148 | use serde_json::Result; 149 | 150 | #[derive(Serialize, Deserialize)] 151 | struct Person { 152 | name: String, 153 | age: u8, 154 | phones: Vec, 155 | } 156 | 157 | fn typed_example() -> Result<()> { 158 | // Some JSON input data as a &str. Maybe this comes from the user. 159 | let data = r#" 160 | { 161 | "name": "John Doe", 162 | "age": 43, 163 | "phones": [ 164 | "+44 1234567", 165 | "+44 2345678" 166 | ] 167 | }"#; 168 | 169 | // Parse the string of data into a Person object. This is exactly the 170 | // same function as the one that produced serde_json::Value above, but 171 | // now we are asking it for a Person as output. 172 | let p: Person = serde_json::from_str(data)?; 173 | 174 | // Do things just like with any other Rust data structure. 175 | println!("Please call {} at the number {}", p.name, p.phones[0]); 176 | 177 | Ok(()) 178 | } 179 | ``` 180 | 181 | This is the same `serde_json::from_str` function as before, but this time we 182 | assign the return value to a variable of type `Person` so Serde will 183 | automatically interpret the input data as a `Person` and produce informative 184 | error messages if the layout does not conform to what a `Person` is expected 185 | to look like. 186 | 187 | Any type that implements Serde's `Deserialize` trait can be deserialized 188 | this way. This includes built-in Rust standard library types like `Vec` 189 | and `HashMap`, as well as any structs or enums annotated with 190 | `#[derive(Deserialize)]`. 191 | 192 | Once we have `p` of type `Person`, our IDE and the Rust compiler can help us 193 | use it correctly like they do for any other Rust code. The IDE can 194 | autocomplete field names to prevent typos, which was impossible in the 195 | `serde_json::Value` representation. And the Rust compiler can check that 196 | when we write `p.phones[0]`, then `p.phones` is guaranteed to be a 197 | `Vec` so indexing into it makes sense and produces a `String`. 198 | 199 | ## Constructing JSON values 200 | 201 | Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` 202 | objects with very natural JSON syntax. 203 | 204 | 205 | 206 | 207 | 208 | ```rust 209 | use serde_json::json; 210 | 211 | fn main() { 212 | // The type of `john` is `serde_json::Value` 213 | let john = json!({ 214 | "name": "John Doe", 215 | "age": 43, 216 | "phones": [ 217 | "+44 1234567", 218 | "+44 2345678" 219 | ] 220 | }); 221 | 222 | println!("first phone number: {}", john["phones"][0]); 223 | 224 | // Convert to a string of JSON and print it out 225 | println!("{}", john.to_string()); 226 | } 227 | ``` 228 | 229 | The `Value::to_string()` function converts a `serde_json::Value` into a 230 | `String` of JSON text. 231 | 232 | One neat thing about the `json!` macro is that variables and expressions can 233 | be interpolated directly into the JSON value as you are building it. Serde 234 | will check at compile time that the value you are interpolating is able to 235 | be represented as JSON. 236 | 237 | 238 | 239 | 240 | 241 | ```rust 242 | let full_name = "John Doe"; 243 | let age_last_year = 42; 244 | 245 | // The type of `john` is `serde_json::Value` 246 | let john = json!({ 247 | "name": full_name, 248 | "age": age_last_year + 1, 249 | "phones": [ 250 | format!("+44 {}", random_phone()) 251 | ] 252 | }); 253 | ``` 254 | 255 | This is amazingly convenient but we have the problem we had before with 256 | `Value` which is that the IDE and Rust compiler cannot help us if we get it 257 | wrong. Serde JSON provides a better way of serializing strongly-typed data 258 | structures into JSON text. 259 | 260 | ## Creating JSON by serializing data structures 261 | 262 | A data structure can be converted to a JSON string by 263 | [`serde_json::to_string`][to_string]. There is also 264 | [`serde_json::to_vec`][to_vec] which serializes to a `Vec` and 265 | [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` 266 | such as a File or a TCP stream. 267 | 268 | 269 | 270 | 271 | 272 | ```rust 273 | use serde::{Deserialize, Serialize}; 274 | use serde_json::Result; 275 | 276 | #[derive(Serialize, Deserialize)] 277 | struct Address { 278 | street: String, 279 | city: String, 280 | } 281 | 282 | fn print_an_address() -> Result<()> { 283 | // Some data structure. 284 | let address = Address { 285 | street: "10 Downing Street".to_owned(), 286 | city: "London".to_owned(), 287 | }; 288 | 289 | // Serialize it to a JSON string. 290 | let j = serde_json::to_string(&address)?; 291 | 292 | // Print, write to a file, or send to an HTTP server. 293 | println!("{}", j); 294 | 295 | Ok(()) 296 | } 297 | ``` 298 | 299 | Any type that implements Serde's `Serialize` trait can be serialized this 300 | way. This includes built-in Rust standard library types like `Vec` and 301 | `HashMap`, as well as any structs or enums annotated with 302 | `#[derive(Serialize)]`. 303 | 304 | ## Performance 305 | 306 | It is fast. You should expect in the ballpark of 500 to 1000 megabytes per 307 | second deserialization and 600 to 900 megabytes per second serialization, 308 | depending on the characteristics of your data. This is competitive with the 309 | fastest C and C++ JSON libraries or even 30% faster for many use cases. 310 | Benchmarks live in the [serde-rs/json-benchmark] repo. 311 | 312 | [serde-rs/json-benchmark]: https://github.com/serde-rs/json-benchmark 313 | 314 | ## Getting help 315 | 316 | Serde developers live in the #serde channel on 317 | [`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a 318 | good resource with generally faster response time but less specific knowledge 319 | about Serde. If IRC is not your thing, we are happy to respond to [GitHub 320 | issues](https://github.com/serde-rs/json/issues/new) as well. 321 | 322 | ## No-std support 323 | 324 | This crate currently requires the Rust standard library. For JSON support in 325 | Serde without a standard library, please see the [`serde-json-core`] crate. 326 | 327 | [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/ 328 | 329 | [value]: https://docs.serde.rs/serde_json/value/enum.Value.html 330 | [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html 331 | [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html 332 | [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html 333 | [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html 334 | [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html 335 | [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html 336 | [macro]: https://docs.serde.rs/serde_json/macro.json.html 337 | 338 |
339 | 340 | #### License 341 | 342 | 343 | Licensed under either of Apache License, Version 344 | 2.0 or MIT license at your option. 345 | 346 | 347 |
348 | 349 | 350 | Unless you explicitly state otherwise, any contribution intentionally submitted 351 | for inclusion in this crate by you, as defined in the Apache-2.0 license, shall 352 | be dual licensed as above, without any additional terms or conditions. 353 | 354 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 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 | //! ```edition2018 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), 53 | //! Object(Map), 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 | //! ```edition2018 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 | //! ```edition2018 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, 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` 168 | //! and `HashMap`, 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` 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 | //! ```edition2018 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 | //! ```edition2018 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` 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 | //! ```edition2018 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` and 276 | //! `HashMap`, as well as any structs or enums annotated with 277 | //! `#[derive(Serialize)]`. 278 | //! 279 | //! # No-std support 280 | //! 281 | //! This crate currently requires the Rust standard library. For JSON support in 282 | //! Serde without a standard library, please see the [`serde-json-core`] crate. 283 | //! 284 | //! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html 285 | //! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html 286 | //! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html 287 | //! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html 288 | //! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html 289 | //! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html 290 | //! [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html 291 | //! [macro]: https://docs.serde.rs/serde_json/macro.json.html 292 | //! [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/ 293 | 294 | #![doc(html_root_url = "https://docs.rs/serde_json/1.0.44")] 295 | #![allow(unknown_lints, bare_trait_objects, ellipsis_inclusive_range_patterns)] 296 | #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] 297 | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] 298 | // Ignored clippy lints 299 | #![cfg_attr( 300 | feature = "cargo-clippy", 301 | allow(deprecated_cfg_attr, doc_markdown, needless_doctest_main) 302 | )] 303 | // Ignored clippy_pedantic lints 304 | #![cfg_attr(feature = "cargo-clippy", allow( 305 | // Deserializer::from_str, into_iter 306 | should_implement_trait, 307 | // integer and float ser/de requires these sorts of casts 308 | cast_possible_wrap, 309 | cast_precision_loss, 310 | cast_sign_loss, 311 | // correctly used 312 | integer_division, 313 | // things are often more readable this way 314 | cast_lossless, 315 | module_name_repetitions, 316 | shadow_unrelated, 317 | single_match_else, 318 | too_many_lines, 319 | use_self, 320 | zero_prefixed_literal, 321 | // we support older compilers 322 | checked_conversions, 323 | redundant_field_names, 324 | // noisy 325 | must_use_candidate, 326 | ))] 327 | #![deny(missing_docs)] 328 | 329 | #[macro_use] 330 | extern crate serde; 331 | #[cfg(feature = "preserve_order")] 332 | extern crate indexmap; 333 | extern crate itoa; 334 | extern crate ryu; 335 | 336 | #[doc(inline)] 337 | pub use self::de::{from_reader, from_slice, from_str, Deserializer, StreamDeserializer}; 338 | #[doc(inline)] 339 | pub use self::error::{Error, Result}; 340 | #[doc(inline)] 341 | pub use self::ser::{ 342 | to_string, to_string_pretty, to_vec, to_vec_pretty, to_writer, to_writer_pretty, Serializer, 343 | }; 344 | #[doc(inline)] 345 | pub use self::value::{from_value, to_value, Map, Number, Value}; 346 | 347 | // We only use our own error type; no need for From conversions provided by the 348 | // standard library's try! macro. This reduces lines of LLVM IR by 4%. 349 | macro_rules! try { 350 | ($e:expr) => { 351 | match $e { 352 | ::std::result::Result::Ok(val) => val, 353 | ::std::result::Result::Err(err) => return ::std::result::Result::Err(err), 354 | } 355 | }; 356 | } 357 | 358 | #[macro_use] 359 | mod macros; 360 | 361 | pub mod de; 362 | pub mod error; 363 | pub mod map; 364 | pub mod ser; 365 | pub mod value; 366 | 367 | mod iter; 368 | mod number; 369 | mod read; 370 | 371 | #[cfg(feature = "raw_value")] 372 | mod raw; 373 | -------------------------------------------------------------------------------- /src/raw.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{self, Debug, Display}; 2 | use std::mem; 3 | 4 | use serde::de::value::BorrowedStrDeserializer; 5 | use serde::de::{ 6 | self, Deserialize, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, Unexpected, 7 | Visitor, 8 | }; 9 | use serde::ser::{Serialize, SerializeStruct, Serializer}; 10 | 11 | use error::Error; 12 | 13 | /// Reference to a range of bytes encompassing a single valid JSON value in the 14 | /// input data. 15 | /// 16 | /// A `RawValue` can be used to defer parsing parts of a payload until later, 17 | /// or to avoid parsing it at all in the case that part of the payload just 18 | /// needs to be transferred verbatim into a different output object. 19 | /// 20 | /// When serializing, a value of this type will retain its original formatting 21 | /// and will not be minified or pretty-printed. 22 | /// 23 | /// # Note 24 | /// 25 | /// `RawValue` is only available if serde\_json is built with the `"raw_value"` 26 | /// feature. 27 | /// 28 | /// ```toml 29 | /// [dependencies] 30 | /// serde_json = { version = "1.0", features = ["raw_value"] } 31 | /// ``` 32 | /// 33 | /// # Example 34 | /// 35 | /// ```edition2018 36 | /// use serde::{Deserialize, Serialize}; 37 | /// use serde_json::{Result, value::RawValue}; 38 | /// 39 | /// #[derive(Deserialize)] 40 | /// struct Input<'a> { 41 | /// code: u32, 42 | /// #[serde(borrow)] 43 | /// payload: &'a RawValue, 44 | /// } 45 | /// 46 | /// #[derive(Serialize)] 47 | /// struct Output<'a> { 48 | /// info: (u32, &'a RawValue), 49 | /// } 50 | /// 51 | /// // Efficiently rearrange JSON input containing separate "code" and "payload" 52 | /// // keys into a single "info" key holding an array of code and payload. 53 | /// // 54 | /// // This could be done equivalently using serde_json::Value as the type for 55 | /// // payload, but &RawValue will perform better because it does not require 56 | /// // memory allocation. The correct range of bytes is borrowed from the input 57 | /// // data and pasted verbatim into the output. 58 | /// fn rearrange(input: &str) -> Result { 59 | /// let input: Input = serde_json::from_str(input)?; 60 | /// 61 | /// let output = Output { 62 | /// info: (input.code, input.payload), 63 | /// }; 64 | /// 65 | /// serde_json::to_string(&output) 66 | /// } 67 | /// 68 | /// fn main() -> Result<()> { 69 | /// let out = rearrange(r#" {"code": 200, "payload": {}} "#)?; 70 | /// 71 | /// assert_eq!(out, r#"{"info":[200,{}]}"#); 72 | /// 73 | /// Ok(()) 74 | /// } 75 | /// ``` 76 | /// 77 | /// # Ownership 78 | /// 79 | /// The typical usage of `RawValue` will be in the borrowed form: 80 | /// 81 | /// ```edition2018 82 | /// # use serde::Deserialize; 83 | /// # use serde_json::value::RawValue; 84 | /// # 85 | /// #[derive(Deserialize)] 86 | /// struct SomeStruct<'a> { 87 | /// #[serde(borrow)] 88 | /// raw_value: &'a RawValue, 89 | /// } 90 | /// ``` 91 | /// 92 | /// The borrowed form is suitable when deserializing through 93 | /// [`serde_json::from_str`] and [`serde_json::from_slice`] which support 94 | /// borrowing from the input data without memory allocation. 95 | /// 96 | /// When deserializing through [`serde_json::from_reader`] you will need to use 97 | /// the boxed form of `RawValue` instead. This is almost as efficient but 98 | /// involves buffering the raw value from the I/O stream into memory. 99 | /// 100 | /// [`serde_json::from_str`]: ../fn.from_str.html 101 | /// [`serde_json::from_slice`]: ../fn.from_slice.html 102 | /// [`serde_json::from_reader`]: ../fn.from_reader.html 103 | /// 104 | /// ```edition2018 105 | /// # use serde::Deserialize; 106 | /// # use serde_json::value::RawValue; 107 | /// # 108 | /// #[derive(Deserialize)] 109 | /// struct SomeStruct { 110 | /// raw_value: Box, 111 | /// } 112 | /// ``` 113 | #[repr(C)] 114 | pub struct RawValue { 115 | json: str, 116 | } 117 | 118 | impl RawValue { 119 | fn from_borrowed(json: &str) -> &Self { 120 | unsafe { mem::transmute::<&str, &RawValue>(json) } 121 | } 122 | 123 | fn from_owned(json: Box) -> Box { 124 | unsafe { mem::transmute::, Box>(json) } 125 | } 126 | } 127 | 128 | impl Clone for Box { 129 | fn clone(&self) -> Self { 130 | (**self).to_owned() 131 | } 132 | } 133 | 134 | impl ToOwned for RawValue { 135 | type Owned = Box; 136 | 137 | fn to_owned(&self) -> Self::Owned { 138 | RawValue::from_owned(self.json.to_owned().into_boxed_str()) 139 | } 140 | } 141 | 142 | impl Default for Box { 143 | fn default() -> Self { 144 | RawValue::from_borrowed("null").to_owned() 145 | } 146 | } 147 | 148 | impl Debug for RawValue { 149 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 150 | formatter 151 | .debug_tuple("RawValue") 152 | .field(&format_args!("{}", &self.json)) 153 | .finish() 154 | } 155 | } 156 | 157 | impl Display for RawValue { 158 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 159 | f.write_str(&self.json) 160 | } 161 | } 162 | 163 | impl RawValue { 164 | /// Convert an owned `String` of JSON data to an owned `RawValue`. 165 | /// 166 | /// This function is equivalent to `serde_json::from_str::>` 167 | /// except that we avoid an allocation and memcpy if both of the following 168 | /// are true: 169 | /// 170 | /// - the input has no leading or trailing whitespace, and 171 | /// - the input has capacity equal to its length. 172 | pub fn from_string(json: String) -> Result, Error> { 173 | { 174 | let borrowed = ::from_str::<&Self>(&json)?; 175 | if borrowed.json.len() < json.len() { 176 | return Ok(borrowed.to_owned()); 177 | } 178 | } 179 | Ok(Self::from_owned(json.into_boxed_str())) 180 | } 181 | 182 | /// Access the JSON text underlying a raw value. 183 | /// 184 | /// # Example 185 | /// 186 | /// ```edition2018 187 | /// use serde::Deserialize; 188 | /// use serde_json::{Result, value::RawValue}; 189 | /// 190 | /// #[derive(Deserialize)] 191 | /// struct Response<'a> { 192 | /// code: u32, 193 | /// #[serde(borrow)] 194 | /// payload: &'a RawValue, 195 | /// } 196 | /// 197 | /// fn process(input: &str) -> Result<()> { 198 | /// let response: Response = serde_json::from_str(input)?; 199 | /// 200 | /// let payload = response.payload.get(); 201 | /// if payload.starts_with('{') { 202 | /// // handle a payload which is a JSON map 203 | /// } else { 204 | /// // handle any other type 205 | /// } 206 | /// 207 | /// Ok(()) 208 | /// } 209 | /// 210 | /// fn main() -> Result<()> { 211 | /// process(r#" {"code": 200, "payload": {}} "#)?; 212 | /// Ok(()) 213 | /// } 214 | /// ``` 215 | pub fn get(&self) -> &str { 216 | &self.json 217 | } 218 | } 219 | 220 | pub const TOKEN: &'static str = "$serde_json::private::RawValue"; 221 | 222 | impl Serialize for RawValue { 223 | fn serialize(&self, serializer: S) -> Result 224 | where 225 | S: Serializer, 226 | { 227 | let mut s = serializer.serialize_struct(TOKEN, 1)?; 228 | s.serialize_field(TOKEN, &self.json)?; 229 | s.end() 230 | } 231 | } 232 | 233 | impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue { 234 | fn deserialize(deserializer: D) -> Result 235 | where 236 | D: Deserializer<'de>, 237 | { 238 | struct ReferenceVisitor; 239 | 240 | impl<'de> Visitor<'de> for ReferenceVisitor { 241 | type Value = &'de RawValue; 242 | 243 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 244 | write!(formatter, "any valid JSON value") 245 | } 246 | 247 | fn visit_map(self, mut visitor: V) -> Result 248 | where 249 | V: MapAccess<'de>, 250 | { 251 | let value = visitor.next_key::()?; 252 | if value.is_none() { 253 | return Err(de::Error::invalid_type(Unexpected::Map, &self)); 254 | } 255 | visitor.next_value_seed(ReferenceFromString) 256 | } 257 | } 258 | 259 | deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor) 260 | } 261 | } 262 | 263 | impl<'de> Deserialize<'de> for Box { 264 | fn deserialize(deserializer: D) -> Result 265 | where 266 | D: Deserializer<'de>, 267 | { 268 | struct BoxedVisitor; 269 | 270 | impl<'de> Visitor<'de> for BoxedVisitor { 271 | type Value = Box; 272 | 273 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 274 | write!(formatter, "any valid JSON value") 275 | } 276 | 277 | fn visit_map(self, mut visitor: V) -> Result 278 | where 279 | V: MapAccess<'de>, 280 | { 281 | let value = visitor.next_key::()?; 282 | if value.is_none() { 283 | return Err(de::Error::invalid_type(Unexpected::Map, &self)); 284 | } 285 | visitor.next_value_seed(BoxedFromString) 286 | } 287 | } 288 | 289 | deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor) 290 | } 291 | } 292 | 293 | struct RawKey; 294 | 295 | impl<'de> Deserialize<'de> for RawKey { 296 | fn deserialize(deserializer: D) -> Result 297 | where 298 | D: Deserializer<'de>, 299 | { 300 | struct FieldVisitor; 301 | 302 | impl<'de> Visitor<'de> for FieldVisitor { 303 | type Value = (); 304 | 305 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 306 | formatter.write_str("raw value") 307 | } 308 | 309 | fn visit_str(self, s: &str) -> Result<(), E> 310 | where 311 | E: de::Error, 312 | { 313 | if s == TOKEN { 314 | Ok(()) 315 | } else { 316 | Err(de::Error::custom("unexpected raw value")) 317 | } 318 | } 319 | } 320 | 321 | deserializer.deserialize_identifier(FieldVisitor)?; 322 | Ok(RawKey) 323 | } 324 | } 325 | 326 | pub struct ReferenceFromString; 327 | 328 | impl<'de> DeserializeSeed<'de> for ReferenceFromString { 329 | type Value = &'de RawValue; 330 | 331 | fn deserialize(self, deserializer: D) -> Result 332 | where 333 | D: Deserializer<'de>, 334 | { 335 | deserializer.deserialize_str(self) 336 | } 337 | } 338 | 339 | impl<'de> Visitor<'de> for ReferenceFromString { 340 | type Value = &'de RawValue; 341 | 342 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 343 | formatter.write_str("raw value") 344 | } 345 | 346 | fn visit_borrowed_str(self, s: &'de str) -> Result 347 | where 348 | E: de::Error, 349 | { 350 | Ok(RawValue::from_borrowed(s)) 351 | } 352 | } 353 | 354 | pub struct BoxedFromString; 355 | 356 | impl<'de> DeserializeSeed<'de> for BoxedFromString { 357 | type Value = Box; 358 | 359 | fn deserialize(self, deserializer: D) -> Result 360 | where 361 | D: Deserializer<'de>, 362 | { 363 | deserializer.deserialize_str(self) 364 | } 365 | } 366 | 367 | impl<'de> Visitor<'de> for BoxedFromString { 368 | type Value = Box; 369 | 370 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 371 | formatter.write_str("raw value") 372 | } 373 | 374 | fn visit_str(self, s: &str) -> Result 375 | where 376 | E: de::Error, 377 | { 378 | self.visit_string(s.to_owned()) 379 | } 380 | 381 | fn visit_string(self, s: String) -> Result 382 | where 383 | E: de::Error, 384 | { 385 | Ok(RawValue::from_owned(s.into_boxed_str())) 386 | } 387 | } 388 | 389 | struct RawKeyDeserializer; 390 | 391 | impl<'de> Deserializer<'de> for RawKeyDeserializer { 392 | type Error = Error; 393 | 394 | fn deserialize_any(self, visitor: V) -> Result 395 | where 396 | V: de::Visitor<'de>, 397 | { 398 | visitor.visit_borrowed_str(TOKEN) 399 | } 400 | 401 | forward_to_deserialize_any! { 402 | bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq 403 | bytes byte_buf map struct option unit newtype_struct ignored_any 404 | unit_struct tuple_struct tuple enum identifier 405 | } 406 | } 407 | 408 | pub struct OwnedRawDeserializer { 409 | pub raw_value: Option, 410 | } 411 | 412 | impl<'de> MapAccess<'de> for OwnedRawDeserializer { 413 | type Error = Error; 414 | 415 | fn next_key_seed(&mut self, seed: K) -> Result, Error> 416 | where 417 | K: de::DeserializeSeed<'de>, 418 | { 419 | if self.raw_value.is_none() { 420 | return Ok(None); 421 | } 422 | seed.deserialize(RawKeyDeserializer).map(Some) 423 | } 424 | 425 | fn next_value_seed(&mut self, seed: V) -> Result 426 | where 427 | V: de::DeserializeSeed<'de>, 428 | { 429 | seed.deserialize(self.raw_value.take().unwrap().into_deserializer()) 430 | } 431 | } 432 | 433 | pub struct BorrowedRawDeserializer<'de> { 434 | pub raw_value: Option<&'de str>, 435 | } 436 | 437 | impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> { 438 | type Error = Error; 439 | 440 | fn next_key_seed(&mut self, seed: K) -> Result, Error> 441 | where 442 | K: de::DeserializeSeed<'de>, 443 | { 444 | if self.raw_value.is_none() { 445 | return Ok(None); 446 | } 447 | seed.deserialize(RawKeyDeserializer).map(Some) 448 | } 449 | 450 | fn next_value_seed(&mut self, seed: V) -> Result 451 | where 452 | V: de::DeserializeSeed<'de>, 453 | { 454 | seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap())) 455 | } 456 | } 457 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | //! When serializing or deserializing JSON goes wrong. 2 | 3 | use std::error; 4 | use std::fmt::{self, Debug, Display}; 5 | use std::io; 6 | use std::result; 7 | use std::str::FromStr; 8 | 9 | use serde::de; 10 | use serde::ser; 11 | 12 | /// This type represents all possible errors that can occur when serializing or 13 | /// deserializing JSON data. 14 | pub struct Error { 15 | /// This `Box` allows us to keep the size of `Error` as small as possible. A 16 | /// larger `Error` type was substantially slower due to all the functions 17 | /// that pass around `Result`. 18 | err: Box, 19 | } 20 | 21 | /// Alias for a `Result` with the error type `serde_json::Error`. 22 | pub type Result = result::Result; 23 | 24 | impl Error { 25 | /// One-based line number at which the error was detected. 26 | /// 27 | /// Characters in the first line of the input (before the first newline 28 | /// character) are in line 1. 29 | pub fn line(&self) -> usize { 30 | self.err.line 31 | } 32 | 33 | /// One-based column number at which the error was detected. 34 | /// 35 | /// The first character in the input and any characters immediately 36 | /// following a newline character are in column 1. 37 | /// 38 | /// Note that errors may occur in column 0, for example if a read from an IO 39 | /// stream fails immediately following a previously read newline character. 40 | pub fn column(&self) -> usize { 41 | self.err.column 42 | } 43 | 44 | /// Categorizes the cause of this error. 45 | /// 46 | /// - `Category::Io` - failure to read or write bytes on an IO stream 47 | /// - `Category::Syntax` - input that is not syntactically valid JSON 48 | /// - `Category::Data` - input data that is semantically incorrect 49 | /// - `Category::Eof` - unexpected end of the input data 50 | pub fn classify(&self) -> Category { 51 | match self.err.code { 52 | ErrorCode::Message(_) => Category::Data, 53 | ErrorCode::Io(_) => Category::Io, 54 | ErrorCode::EofWhileParsingList 55 | | ErrorCode::EofWhileParsingObject 56 | | ErrorCode::EofWhileParsingString 57 | | ErrorCode::EofWhileParsingValue => Category::Eof, 58 | ErrorCode::ExpectedColon 59 | | ErrorCode::ExpectedListCommaOrEnd 60 | | ErrorCode::ExpectedObjectCommaOrEnd 61 | | ErrorCode::ExpectedObjectOrArray 62 | | ErrorCode::ExpectedSomeIdent 63 | | ErrorCode::ExpectedSomeValue 64 | | ErrorCode::ExpectedSomeString 65 | | ErrorCode::InvalidEscape 66 | | ErrorCode::InvalidNumber 67 | | ErrorCode::NumberOutOfRange 68 | | ErrorCode::InvalidUnicodeCodePoint 69 | | ErrorCode::ControlCharacterWhileParsingString 70 | | ErrorCode::KeyMustBeAString 71 | | ErrorCode::LoneLeadingSurrogateInHexEscape 72 | | ErrorCode::TrailingComma 73 | | ErrorCode::TrailingCharacters 74 | | ErrorCode::UnexpectedEndOfHexEscape 75 | | ErrorCode::RecursionLimitExceeded => Category::Syntax, 76 | } 77 | } 78 | 79 | /// Returns true if this error was caused by a failure to read or write 80 | /// bytes on an IO stream. 81 | pub fn is_io(&self) -> bool { 82 | self.classify() == Category::Io 83 | } 84 | 85 | /// Returns true if this error was caused by input that was not 86 | /// syntactically valid JSON. 87 | pub fn is_syntax(&self) -> bool { 88 | self.classify() == Category::Syntax 89 | } 90 | 91 | /// Returns true if this error was caused by input data that was 92 | /// semantically incorrect. 93 | /// 94 | /// For example, JSON containing a number is semantically incorrect when the 95 | /// type being deserialized into holds a String. 96 | pub fn is_data(&self) -> bool { 97 | self.classify() == Category::Data 98 | } 99 | 100 | /// Returns true if this error was caused by prematurely reaching the end of 101 | /// the input data. 102 | /// 103 | /// Callers that process streaming input may be interested in retrying the 104 | /// deserialization once more data is available. 105 | pub fn is_eof(&self) -> bool { 106 | self.classify() == Category::Eof 107 | } 108 | } 109 | 110 | /// Categorizes the cause of a `serde_json::Error`. 111 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] 112 | pub enum Category { 113 | /// The error was caused by a failure to read or write bytes on an IO 114 | /// stream. 115 | Io, 116 | 117 | /// The error was caused by input that was not syntactically valid JSON. 118 | Syntax, 119 | 120 | /// The error was caused by input data that was semantically incorrect. 121 | /// 122 | /// For example, JSON containing a number is semantically incorrect when the 123 | /// type being deserialized into holds a String. 124 | Data, 125 | 126 | /// The error was caused by prematurely reaching the end of the input data. 127 | /// 128 | /// Callers that process streaming input may be interested in retrying the 129 | /// deserialization once more data is available. 130 | Eof, 131 | } 132 | 133 | #[cfg_attr(feature = "cargo-clippy", allow(fallible_impl_from))] 134 | impl From for io::Error { 135 | /// Convert a `serde_json::Error` into an `io::Error`. 136 | /// 137 | /// JSON syntax and data errors are turned into `InvalidData` IO errors. 138 | /// EOF errors are turned into `UnexpectedEof` IO errors. 139 | /// 140 | /// ```edition2018 141 | /// use std::io; 142 | /// 143 | /// enum MyError { 144 | /// Io(io::Error), 145 | /// Json(serde_json::Error), 146 | /// } 147 | /// 148 | /// impl From for MyError { 149 | /// fn from(err: serde_json::Error) -> MyError { 150 | /// use serde_json::error::Category; 151 | /// match err.classify() { 152 | /// Category::Io => { 153 | /// MyError::Io(err.into()) 154 | /// } 155 | /// Category::Syntax | Category::Data | Category::Eof => { 156 | /// MyError::Json(err) 157 | /// } 158 | /// } 159 | /// } 160 | /// } 161 | /// ``` 162 | fn from(j: Error) -> Self { 163 | if let ErrorCode::Io(err) = j.err.code { 164 | err 165 | } else { 166 | match j.classify() { 167 | Category::Io => unreachable!(), 168 | Category::Syntax | Category::Data => io::Error::new(io::ErrorKind::InvalidData, j), 169 | Category::Eof => io::Error::new(io::ErrorKind::UnexpectedEof, j), 170 | } 171 | } 172 | } 173 | } 174 | 175 | struct ErrorImpl { 176 | code: ErrorCode, 177 | line: usize, 178 | column: usize, 179 | } 180 | 181 | // Not public API. Should be pub(crate). 182 | #[doc(hidden)] 183 | pub enum ErrorCode { 184 | /// Catchall for syntax error messages 185 | Message(Box), 186 | 187 | /// Some IO error occurred while serializing or deserializing. 188 | Io(io::Error), 189 | 190 | /// EOF while parsing a list. 191 | EofWhileParsingList, 192 | 193 | /// EOF while parsing an object. 194 | EofWhileParsingObject, 195 | 196 | /// EOF while parsing a string. 197 | EofWhileParsingString, 198 | 199 | /// EOF while parsing a JSON value. 200 | EofWhileParsingValue, 201 | 202 | /// Expected this character to be a `':'`. 203 | ExpectedColon, 204 | 205 | /// Expected this character to be either a `','` or a `']'`. 206 | ExpectedListCommaOrEnd, 207 | 208 | /// Expected this character to be either a `','` or a `'}'`. 209 | ExpectedObjectCommaOrEnd, 210 | 211 | /// Expected this character to be either a `'{'` or a `'['`. 212 | ExpectedObjectOrArray, 213 | 214 | /// Expected to parse either a `true`, `false`, or a `null`. 215 | ExpectedSomeIdent, 216 | 217 | /// Expected this character to start a JSON value. 218 | ExpectedSomeValue, 219 | 220 | /// Expected this character to start a JSON string. 221 | ExpectedSomeString, 222 | 223 | /// Invalid hex escape code. 224 | InvalidEscape, 225 | 226 | /// Invalid number. 227 | InvalidNumber, 228 | 229 | /// Number is bigger than the maximum value of its type. 230 | NumberOutOfRange, 231 | 232 | /// Invalid unicode code point. 233 | InvalidUnicodeCodePoint, 234 | 235 | /// Control character found while parsing a string. 236 | ControlCharacterWhileParsingString, 237 | 238 | /// Object key is not a string. 239 | KeyMustBeAString, 240 | 241 | /// Lone leading surrogate in hex escape. 242 | LoneLeadingSurrogateInHexEscape, 243 | 244 | /// JSON has a comma after the last value in an array or map. 245 | TrailingComma, 246 | 247 | /// JSON has non-whitespace trailing characters after the value. 248 | TrailingCharacters, 249 | 250 | /// Unexpected end of hex excape. 251 | UnexpectedEndOfHexEscape, 252 | 253 | /// Encountered nesting of JSON maps and arrays more than 128 layers deep. 254 | RecursionLimitExceeded, 255 | } 256 | 257 | impl Error { 258 | // Not public API. Should be pub(crate). 259 | #[doc(hidden)] 260 | #[cold] 261 | pub fn syntax(code: ErrorCode, line: usize, column: usize) -> Self { 262 | Error { 263 | err: Box::new(ErrorImpl { 264 | code: code, 265 | line: line, 266 | column: column, 267 | }), 268 | } 269 | } 270 | 271 | // Not public API. Should be pub(crate). 272 | // 273 | // Update `eager_json` crate when this function changes. 274 | #[doc(hidden)] 275 | #[cold] 276 | pub fn io(error: io::Error) -> Self { 277 | Error { 278 | err: Box::new(ErrorImpl { 279 | code: ErrorCode::Io(error), 280 | line: 0, 281 | column: 0, 282 | }), 283 | } 284 | } 285 | 286 | // Not public API. Should be pub(crate). 287 | #[doc(hidden)] 288 | #[cold] 289 | pub fn fix_position(self, f: F) -> Self 290 | where 291 | F: FnOnce(ErrorCode) -> Error, 292 | { 293 | if self.err.line == 0 { 294 | f(self.err.code) 295 | } else { 296 | self 297 | } 298 | } 299 | } 300 | 301 | impl Display for ErrorCode { 302 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 303 | match *self { 304 | ErrorCode::Message(ref msg) => f.write_str(msg), 305 | ErrorCode::Io(ref err) => Display::fmt(err, f), 306 | ErrorCode::EofWhileParsingList => f.write_str("EOF while parsing a list"), 307 | ErrorCode::EofWhileParsingObject => f.write_str("EOF while parsing an object"), 308 | ErrorCode::EofWhileParsingString => f.write_str("EOF while parsing a string"), 309 | ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"), 310 | ErrorCode::ExpectedColon => f.write_str("expected `:`"), 311 | ErrorCode::ExpectedListCommaOrEnd => f.write_str("expected `,` or `]`"), 312 | ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"), 313 | ErrorCode::ExpectedObjectOrArray => f.write_str("expected `{` or `[`"), 314 | ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"), 315 | ErrorCode::ExpectedSomeValue => f.write_str("expected value"), 316 | ErrorCode::ExpectedSomeString => f.write_str("expected string"), 317 | ErrorCode::InvalidEscape => f.write_str("invalid escape"), 318 | ErrorCode::InvalidNumber => f.write_str("invalid number"), 319 | ErrorCode::NumberOutOfRange => f.write_str("number out of range"), 320 | ErrorCode::InvalidUnicodeCodePoint => f.write_str("invalid unicode code point"), 321 | ErrorCode::ControlCharacterWhileParsingString => { 322 | f.write_str("control character (\\u0000-\\u001F) found while parsing a string") 323 | } 324 | ErrorCode::KeyMustBeAString => f.write_str("key must be a string"), 325 | ErrorCode::LoneLeadingSurrogateInHexEscape => { 326 | f.write_str("lone leading surrogate in hex escape") 327 | } 328 | ErrorCode::TrailingComma => f.write_str("trailing comma"), 329 | ErrorCode::TrailingCharacters => f.write_str("trailing characters"), 330 | ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"), 331 | ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"), 332 | } 333 | } 334 | } 335 | 336 | impl error::Error for Error { 337 | fn description(&self) -> &str { 338 | match self.err.code { 339 | ErrorCode::Io(ref err) => error::Error::description(err), 340 | _ => { 341 | // If you want a better message, use Display::fmt or to_string(). 342 | "JSON error" 343 | } 344 | } 345 | } 346 | 347 | fn cause(&self) -> Option<&error::Error> { 348 | match self.err.code { 349 | ErrorCode::Io(ref err) => Some(err), 350 | _ => None, 351 | } 352 | } 353 | } 354 | 355 | impl Display for Error { 356 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 357 | Display::fmt(&*self.err, f) 358 | } 359 | } 360 | 361 | impl Display for ErrorImpl { 362 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 363 | if self.line == 0 { 364 | Display::fmt(&self.code, f) 365 | } else { 366 | write!( 367 | f, 368 | "{} at line {} column {}", 369 | self.code, self.line, self.column 370 | ) 371 | } 372 | } 373 | } 374 | 375 | // Remove two layers of verbosity from the debug representation. Humans often 376 | // end up seeing this representation because it is what unwrap() shows. 377 | impl Debug for Error { 378 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 379 | write!( 380 | f, 381 | "Error({:?}, line: {}, column: {})", 382 | self.err.code.to_string(), 383 | self.err.line, 384 | self.err.column 385 | ) 386 | } 387 | } 388 | 389 | impl de::Error for Error { 390 | #[cold] 391 | fn custom(msg: T) -> Error { 392 | make_error(msg.to_string()) 393 | } 394 | 395 | #[cold] 396 | fn invalid_type(unexp: de::Unexpected, exp: &de::Expected) -> Self { 397 | if let de::Unexpected::Unit = unexp { 398 | Error::custom(format_args!("invalid type: null, expected {}", exp)) 399 | } else { 400 | Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) 401 | } 402 | } 403 | } 404 | 405 | impl ser::Error for Error { 406 | #[cold] 407 | fn custom(msg: T) -> Error { 408 | make_error(msg.to_string()) 409 | } 410 | } 411 | 412 | // Parse our own error message that looks like "{} at line {} column {}" to work 413 | // around erased-serde round-tripping the error through de::Error::custom. 414 | fn make_error(mut msg: String) -> Error { 415 | let (line, column) = parse_line_col(&mut msg).unwrap_or((0, 0)); 416 | Error { 417 | err: Box::new(ErrorImpl { 418 | code: ErrorCode::Message(msg.into_boxed_str()), 419 | line: line, 420 | column: column, 421 | }), 422 | } 423 | } 424 | 425 | fn parse_line_col(msg: &mut String) -> Option<(usize, usize)> { 426 | let start_of_suffix = match msg.rfind(" at line ") { 427 | Some(index) => index, 428 | None => return None, 429 | }; 430 | 431 | // Find start and end of line number. 432 | let start_of_line = start_of_suffix + " at line ".len(); 433 | let mut end_of_line = start_of_line; 434 | while starts_with_digit(&msg[end_of_line..]) { 435 | end_of_line += 1; 436 | } 437 | 438 | if !msg[end_of_line..].starts_with(" column ") { 439 | return None; 440 | } 441 | 442 | // Find start and end of column number. 443 | let start_of_column = end_of_line + " column ".len(); 444 | let mut end_of_column = start_of_column; 445 | while starts_with_digit(&msg[end_of_column..]) { 446 | end_of_column += 1; 447 | } 448 | 449 | if end_of_column < msg.len() { 450 | return None; 451 | } 452 | 453 | // Parse numbers. 454 | let line = match usize::from_str(&msg[start_of_line..end_of_line]) { 455 | Ok(line) => line, 456 | Err(_) => return None, 457 | }; 458 | let column = match usize::from_str(&msg[start_of_column..end_of_column]) { 459 | Ok(column) => column, 460 | Err(_) => return None, 461 | }; 462 | 463 | msg.truncate(start_of_suffix); 464 | Some((line, column)) 465 | } 466 | 467 | fn starts_with_digit(slice: &str) -> bool { 468 | match slice.as_bytes().get(0) { 469 | None => false, 470 | Some(&byte) => byte >= b'0' && byte <= b'9', 471 | } 472 | } 473 | -------------------------------------------------------------------------------- /src/number.rs: -------------------------------------------------------------------------------- 1 | use error::Error; 2 | use serde::de::{self, Unexpected, Visitor}; 3 | use serde::{Deserialize, Deserializer, Serialize, Serializer}; 4 | use std::fmt::{self, Debug, Display}; 5 | 6 | #[cfg(feature = "arbitrary_precision")] 7 | use itoa; 8 | #[cfg(feature = "arbitrary_precision")] 9 | use ryu; 10 | #[cfg(feature = "arbitrary_precision")] 11 | use serde::de::{IntoDeserializer, MapAccess}; 12 | 13 | use de::ParserNumber; 14 | 15 | #[cfg(feature = "arbitrary_precision")] 16 | use error::ErrorCode; 17 | 18 | #[cfg(feature = "arbitrary_precision")] 19 | /// Not public API. Should be pub(crate). 20 | #[doc(hidden)] 21 | pub const TOKEN: &'static str = "$serde_json::private::Number"; 22 | 23 | /// Represents a JSON number, whether integer or floating point. 24 | #[derive(Clone, PartialEq)] 25 | pub struct Number { 26 | n: N, 27 | } 28 | 29 | #[cfg(not(feature = "arbitrary_precision"))] 30 | #[derive(Copy, Clone, PartialEq)] 31 | enum N { 32 | PosInt(u64), 33 | /// Always less than zero. 34 | NegInt(i64), 35 | /// Always finite. 36 | Float(f64), 37 | } 38 | 39 | #[cfg(feature = "arbitrary_precision")] 40 | type N = String; 41 | 42 | impl Number { 43 | /// Returns true if the `Number` is an integer between `i64::MIN` and 44 | /// `i64::MAX`. 45 | /// 46 | /// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to 47 | /// return the integer value. 48 | /// 49 | /// ```edition2018 50 | /// # use serde_json::json; 51 | /// # 52 | /// let big = i64::max_value() as u64 + 10; 53 | /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); 54 | /// 55 | /// assert!(v["a"].is_i64()); 56 | /// 57 | /// // Greater than i64::MAX. 58 | /// assert!(!v["b"].is_i64()); 59 | /// 60 | /// // Numbers with a decimal point are not considered integers. 61 | /// assert!(!v["c"].is_i64()); 62 | /// ``` 63 | #[inline] 64 | pub fn is_i64(&self) -> bool { 65 | #[cfg(not(feature = "arbitrary_precision"))] 66 | match self.n { 67 | N::PosInt(v) => v <= i64::max_value() as u64, 68 | N::NegInt(_) => true, 69 | N::Float(_) => false, 70 | } 71 | #[cfg(feature = "arbitrary_precision")] 72 | self.as_i64().is_some() 73 | } 74 | 75 | /// Returns true if the `Number` is an integer between zero and `u64::MAX`. 76 | /// 77 | /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to 78 | /// return the integer value. 79 | /// 80 | /// ```edition2018 81 | /// # use serde_json::json; 82 | /// # 83 | /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); 84 | /// 85 | /// assert!(v["a"].is_u64()); 86 | /// 87 | /// // Negative integer. 88 | /// assert!(!v["b"].is_u64()); 89 | /// 90 | /// // Numbers with a decimal point are not considered integers. 91 | /// assert!(!v["c"].is_u64()); 92 | /// ``` 93 | #[inline] 94 | pub fn is_u64(&self) -> bool { 95 | #[cfg(not(feature = "arbitrary_precision"))] 96 | match self.n { 97 | N::PosInt(_) => true, 98 | N::NegInt(_) | N::Float(_) => false, 99 | } 100 | #[cfg(feature = "arbitrary_precision")] 101 | self.as_u64().is_some() 102 | } 103 | 104 | /// Returns true if the `Number` can be represented by f64. 105 | /// 106 | /// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to 107 | /// return the floating point value. 108 | /// 109 | /// Currently this function returns true if and only if both `is_i64` and 110 | /// `is_u64` return false but this is not a guarantee in the future. 111 | /// 112 | /// ```edition2018 113 | /// # use serde_json::json; 114 | /// # 115 | /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); 116 | /// 117 | /// assert!(v["a"].is_f64()); 118 | /// 119 | /// // Integers. 120 | /// assert!(!v["b"].is_f64()); 121 | /// assert!(!v["c"].is_f64()); 122 | /// ``` 123 | #[inline] 124 | pub fn is_f64(&self) -> bool { 125 | #[cfg(not(feature = "arbitrary_precision"))] 126 | match self.n { 127 | N::Float(_) => true, 128 | N::PosInt(_) | N::NegInt(_) => false, 129 | } 130 | #[cfg(feature = "arbitrary_precision")] 131 | { 132 | for c in self.n.chars() { 133 | if c == '.' || c == 'e' || c == 'E' { 134 | return self.n.parse::().ok().map_or(false, |f| f.is_finite()); 135 | } 136 | } 137 | false 138 | } 139 | } 140 | 141 | /// If the `Number` is an integer, represent it as i64 if possible. Returns 142 | /// None otherwise. 143 | /// 144 | /// ```edition2018 145 | /// # use serde_json::json; 146 | /// # 147 | /// let big = i64::max_value() as u64 + 10; 148 | /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); 149 | /// 150 | /// assert_eq!(v["a"].as_i64(), Some(64)); 151 | /// assert_eq!(v["b"].as_i64(), None); 152 | /// assert_eq!(v["c"].as_i64(), None); 153 | /// ``` 154 | #[inline] 155 | pub fn as_i64(&self) -> Option { 156 | #[cfg(not(feature = "arbitrary_precision"))] 157 | match self.n { 158 | N::PosInt(n) => { 159 | if n <= i64::max_value() as u64 { 160 | Some(n as i64) 161 | } else { 162 | None 163 | } 164 | } 165 | N::NegInt(n) => Some(n), 166 | N::Float(_) => None, 167 | } 168 | #[cfg(feature = "arbitrary_precision")] 169 | self.n.parse().ok() 170 | } 171 | 172 | /// If the `Number` is an integer, represent it as u64 if possible. Returns 173 | /// None otherwise. 174 | /// 175 | /// ```edition2018 176 | /// # use serde_json::json; 177 | /// # 178 | /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); 179 | /// 180 | /// assert_eq!(v["a"].as_u64(), Some(64)); 181 | /// assert_eq!(v["b"].as_u64(), None); 182 | /// assert_eq!(v["c"].as_u64(), None); 183 | /// ``` 184 | #[inline] 185 | pub fn as_u64(&self) -> Option { 186 | #[cfg(not(feature = "arbitrary_precision"))] 187 | match self.n { 188 | N::PosInt(n) => Some(n), 189 | N::NegInt(_) | N::Float(_) => None, 190 | } 191 | #[cfg(feature = "arbitrary_precision")] 192 | self.n.parse().ok() 193 | } 194 | 195 | /// Represents the number as f64 if possible. Returns None otherwise. 196 | /// 197 | /// ```edition2018 198 | /// # use serde_json::json; 199 | /// # 200 | /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); 201 | /// 202 | /// assert_eq!(v["a"].as_f64(), Some(256.0)); 203 | /// assert_eq!(v["b"].as_f64(), Some(64.0)); 204 | /// assert_eq!(v["c"].as_f64(), Some(-64.0)); 205 | /// ``` 206 | #[inline] 207 | pub fn as_f64(&self) -> Option { 208 | #[cfg(not(feature = "arbitrary_precision"))] 209 | match self.n { 210 | N::PosInt(n) => Some(n as f64), 211 | N::NegInt(n) => Some(n as f64), 212 | N::Float(n) => Some(n), 213 | } 214 | #[cfg(feature = "arbitrary_precision")] 215 | self.n.parse().ok() 216 | } 217 | 218 | /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON 219 | /// numbers. 220 | /// 221 | /// ```edition2018 222 | /// # use std::f64; 223 | /// # 224 | /// # use serde_json::Number; 225 | /// # 226 | /// assert!(Number::from_f64(256.0).is_some()); 227 | /// 228 | /// assert!(Number::from_f64(f64::NAN).is_none()); 229 | /// ``` 230 | #[inline] 231 | pub fn from_f64(f: f64) -> Option { 232 | if f.is_finite() { 233 | let n = { 234 | #[cfg(not(feature = "arbitrary_precision"))] 235 | { 236 | N::Float(f) 237 | } 238 | #[cfg(feature = "arbitrary_precision")] 239 | { 240 | ryu::Buffer::new().format_finite(f).to_owned() 241 | } 242 | }; 243 | Some(Number { n: n }) 244 | } else { 245 | None 246 | } 247 | } 248 | 249 | #[cfg(feature = "arbitrary_precision")] 250 | /// Not public API. Only tests use this. 251 | #[doc(hidden)] 252 | #[inline] 253 | pub fn from_string_unchecked(n: String) -> Self { 254 | Number { n: n } 255 | } 256 | } 257 | 258 | impl fmt::Display for Number { 259 | #[cfg(not(feature = "arbitrary_precision"))] 260 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 261 | match self.n { 262 | N::PosInt(u) => Display::fmt(&u, formatter), 263 | N::NegInt(i) => Display::fmt(&i, formatter), 264 | N::Float(f) => Display::fmt(&f, formatter), 265 | } 266 | } 267 | 268 | #[cfg(feature = "arbitrary_precision")] 269 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 270 | Display::fmt(&self.n, formatter) 271 | } 272 | } 273 | 274 | impl Debug for Number { 275 | #[cfg(not(feature = "arbitrary_precision"))] 276 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 277 | let mut debug = formatter.debug_tuple("Number"); 278 | match self.n { 279 | N::PosInt(i) => { 280 | debug.field(&i); 281 | } 282 | N::NegInt(i) => { 283 | debug.field(&i); 284 | } 285 | N::Float(f) => { 286 | debug.field(&f); 287 | } 288 | } 289 | debug.finish() 290 | } 291 | 292 | #[cfg(feature = "arbitrary_precision")] 293 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 294 | write!(formatter, "Number({})", &self.n) 295 | } 296 | } 297 | 298 | impl Serialize for Number { 299 | #[cfg(not(feature = "arbitrary_precision"))] 300 | #[inline] 301 | fn serialize(&self, serializer: S) -> Result 302 | where 303 | S: Serializer, 304 | { 305 | match self.n { 306 | N::PosInt(u) => serializer.serialize_u64(u), 307 | N::NegInt(i) => serializer.serialize_i64(i), 308 | N::Float(f) => serializer.serialize_f64(f), 309 | } 310 | } 311 | 312 | #[cfg(feature = "arbitrary_precision")] 313 | #[inline] 314 | fn serialize(&self, serializer: S) -> Result 315 | where 316 | S: Serializer, 317 | { 318 | use serde::ser::SerializeStruct; 319 | 320 | let mut s = serializer.serialize_struct(TOKEN, 1)?; 321 | s.serialize_field(TOKEN, &self.n)?; 322 | s.end() 323 | } 324 | } 325 | 326 | impl<'de> Deserialize<'de> for Number { 327 | #[inline] 328 | fn deserialize(deserializer: D) -> Result 329 | where 330 | D: Deserializer<'de>, 331 | { 332 | struct NumberVisitor; 333 | 334 | impl<'de> Visitor<'de> for NumberVisitor { 335 | type Value = Number; 336 | 337 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 338 | formatter.write_str("a JSON number") 339 | } 340 | 341 | #[inline] 342 | fn visit_i64(self, value: i64) -> Result { 343 | Ok(value.into()) 344 | } 345 | 346 | #[inline] 347 | fn visit_u64(self, value: u64) -> Result { 348 | Ok(value.into()) 349 | } 350 | 351 | #[inline] 352 | fn visit_f64(self, value: f64) -> Result 353 | where 354 | E: de::Error, 355 | { 356 | Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number")) 357 | } 358 | 359 | #[cfg(feature = "arbitrary_precision")] 360 | #[inline] 361 | fn visit_map(self, mut visitor: V) -> Result 362 | where 363 | V: de::MapAccess<'de>, 364 | { 365 | let value = visitor.next_key::()?; 366 | if value.is_none() { 367 | return Err(de::Error::invalid_type(Unexpected::Map, &self)); 368 | } 369 | let v: NumberFromString = visitor.next_value()?; 370 | Ok(v.value) 371 | } 372 | } 373 | 374 | deserializer.deserialize_any(NumberVisitor) 375 | } 376 | } 377 | 378 | #[cfg(feature = "arbitrary_precision")] 379 | struct NumberKey; 380 | 381 | #[cfg(feature = "arbitrary_precision")] 382 | impl<'de> de::Deserialize<'de> for NumberKey { 383 | fn deserialize(deserializer: D) -> Result 384 | where 385 | D: de::Deserializer<'de>, 386 | { 387 | struct FieldVisitor; 388 | 389 | impl<'de> de::Visitor<'de> for FieldVisitor { 390 | type Value = (); 391 | 392 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 393 | formatter.write_str("a valid number field") 394 | } 395 | 396 | fn visit_str(self, s: &str) -> Result<(), E> 397 | where 398 | E: de::Error, 399 | { 400 | if s == TOKEN { 401 | Ok(()) 402 | } else { 403 | Err(de::Error::custom("expected field with custom name")) 404 | } 405 | } 406 | } 407 | 408 | deserializer.deserialize_identifier(FieldVisitor)?; 409 | Ok(NumberKey) 410 | } 411 | } 412 | 413 | #[cfg(feature = "arbitrary_precision")] 414 | pub struct NumberFromString { 415 | pub value: Number, 416 | } 417 | 418 | #[cfg(feature = "arbitrary_precision")] 419 | impl<'de> de::Deserialize<'de> for NumberFromString { 420 | fn deserialize(deserializer: D) -> Result 421 | where 422 | D: de::Deserializer<'de>, 423 | { 424 | struct Visitor; 425 | 426 | impl<'de> de::Visitor<'de> for Visitor { 427 | type Value = NumberFromString; 428 | 429 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 430 | formatter.write_str("string containing a number") 431 | } 432 | 433 | fn visit_str(self, s: &str) -> Result 434 | where 435 | E: de::Error, 436 | { 437 | let n = try!(s.parse().map_err(de::Error::custom)); 438 | Ok(NumberFromString { value: n }) 439 | } 440 | } 441 | 442 | deserializer.deserialize_str(Visitor) 443 | } 444 | } 445 | 446 | #[cfg(feature = "arbitrary_precision")] 447 | fn invalid_number() -> Error { 448 | Error::syntax(ErrorCode::InvalidNumber, 0, 0) 449 | } 450 | 451 | macro_rules! deserialize_any { 452 | (@expand [$($num_string:tt)*]) => { 453 | #[cfg(not(feature = "arbitrary_precision"))] 454 | #[inline] 455 | fn deserialize_any(self, visitor: V) -> Result 456 | where 457 | V: Visitor<'de>, 458 | { 459 | match self.n { 460 | N::PosInt(u) => visitor.visit_u64(u), 461 | N::NegInt(i) => visitor.visit_i64(i), 462 | N::Float(f) => visitor.visit_f64(f), 463 | } 464 | } 465 | 466 | #[cfg(feature = "arbitrary_precision")] 467 | #[inline] 468 | fn deserialize_any(self, visitor: V) -> Result 469 | where V: Visitor<'de> 470 | { 471 | if let Some(u) = self.as_u64() { 472 | return visitor.visit_u64(u); 473 | } else if let Some(i) = self.as_i64() { 474 | return visitor.visit_i64(i); 475 | } else if let Some(f) = self.as_f64() { 476 | if ryu::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n { 477 | return visitor.visit_f64(f); 478 | } 479 | } 480 | 481 | visitor.visit_map(NumberDeserializer { 482 | number: Some(self.$($num_string)*), 483 | }) 484 | } 485 | }; 486 | 487 | (owned) => { 488 | deserialize_any!(@expand [n]); 489 | }; 490 | 491 | (ref) => { 492 | deserialize_any!(@expand [n.clone()]); 493 | }; 494 | } 495 | 496 | macro_rules! deserialize_number { 497 | ($deserialize:ident => $visit:ident) => { 498 | #[cfg(not(feature = "arbitrary_precision"))] 499 | fn $deserialize(self, visitor: V) -> Result 500 | where 501 | V: Visitor<'de>, 502 | { 503 | self.deserialize_any(visitor) 504 | } 505 | 506 | #[cfg(feature = "arbitrary_precision")] 507 | fn $deserialize(self, visitor: V) -> Result 508 | where 509 | V: de::Visitor<'de>, 510 | { 511 | visitor.$visit(self.n.parse().map_err(|_| invalid_number())?) 512 | } 513 | } 514 | } 515 | 516 | impl<'de> Deserializer<'de> for Number { 517 | type Error = Error; 518 | 519 | deserialize_any!(owned); 520 | 521 | deserialize_number!(deserialize_i8 => visit_i8); 522 | deserialize_number!(deserialize_i16 => visit_i16); 523 | deserialize_number!(deserialize_i32 => visit_i32); 524 | deserialize_number!(deserialize_i64 => visit_i64); 525 | deserialize_number!(deserialize_u8 => visit_u8); 526 | deserialize_number!(deserialize_u16 => visit_u16); 527 | deserialize_number!(deserialize_u32 => visit_u32); 528 | deserialize_number!(deserialize_u64 => visit_u64); 529 | deserialize_number!(deserialize_f32 => visit_f32); 530 | deserialize_number!(deserialize_f64 => visit_f64); 531 | 532 | serde_if_integer128! { 533 | deserialize_number!(deserialize_i128 => visit_i128); 534 | deserialize_number!(deserialize_u128 => visit_u128); 535 | } 536 | 537 | forward_to_deserialize_any! { 538 | bool char str string bytes byte_buf option unit unit_struct 539 | newtype_struct seq tuple tuple_struct map struct enum identifier 540 | ignored_any 541 | } 542 | } 543 | 544 | impl<'de, 'a> Deserializer<'de> for &'a Number { 545 | type Error = Error; 546 | 547 | deserialize_any!(ref); 548 | 549 | deserialize_number!(deserialize_i8 => visit_i8); 550 | deserialize_number!(deserialize_i16 => visit_i16); 551 | deserialize_number!(deserialize_i32 => visit_i32); 552 | deserialize_number!(deserialize_i64 => visit_i64); 553 | deserialize_number!(deserialize_u8 => visit_u8); 554 | deserialize_number!(deserialize_u16 => visit_u16); 555 | deserialize_number!(deserialize_u32 => visit_u32); 556 | deserialize_number!(deserialize_u64 => visit_u64); 557 | deserialize_number!(deserialize_f32 => visit_f32); 558 | deserialize_number!(deserialize_f64 => visit_f64); 559 | 560 | serde_if_integer128! { 561 | deserialize_number!(deserialize_i128 => visit_i128); 562 | deserialize_number!(deserialize_u128 => visit_u128); 563 | } 564 | 565 | forward_to_deserialize_any! { 566 | bool char str string bytes byte_buf option unit unit_struct 567 | newtype_struct seq tuple tuple_struct map struct enum identifier 568 | ignored_any 569 | } 570 | } 571 | 572 | #[cfg(feature = "arbitrary_precision")] 573 | // Not public API. Should be pub(crate). 574 | #[doc(hidden)] 575 | pub struct NumberDeserializer { 576 | pub number: Option, 577 | } 578 | 579 | #[cfg(feature = "arbitrary_precision")] 580 | impl<'de> MapAccess<'de> for NumberDeserializer { 581 | type Error = Error; 582 | 583 | fn next_key_seed(&mut self, seed: K) -> Result, Error> 584 | where 585 | K: de::DeserializeSeed<'de>, 586 | { 587 | if self.number.is_none() { 588 | return Ok(None); 589 | } 590 | seed.deserialize(NumberFieldDeserializer).map(Some) 591 | } 592 | 593 | fn next_value_seed(&mut self, seed: V) -> Result 594 | where 595 | V: de::DeserializeSeed<'de>, 596 | { 597 | seed.deserialize(self.number.take().unwrap().into_deserializer()) 598 | } 599 | } 600 | 601 | #[cfg(feature = "arbitrary_precision")] 602 | struct NumberFieldDeserializer; 603 | 604 | #[cfg(feature = "arbitrary_precision")] 605 | impl<'de> Deserializer<'de> for NumberFieldDeserializer { 606 | type Error = Error; 607 | 608 | fn deserialize_any(self, visitor: V) -> Result 609 | where 610 | V: de::Visitor<'de>, 611 | { 612 | visitor.visit_borrowed_str(TOKEN) 613 | } 614 | 615 | forward_to_deserialize_any! { 616 | bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq 617 | bytes byte_buf map struct option unit newtype_struct ignored_any 618 | unit_struct tuple_struct tuple enum identifier 619 | } 620 | } 621 | 622 | impl From for Number { 623 | fn from(value: ParserNumber) -> Self { 624 | let n = match value { 625 | ParserNumber::F64(f) => { 626 | #[cfg(not(feature = "arbitrary_precision"))] 627 | { 628 | N::Float(f) 629 | } 630 | #[cfg(feature = "arbitrary_precision")] 631 | { 632 | f.to_string() 633 | } 634 | } 635 | ParserNumber::U64(u) => { 636 | #[cfg(not(feature = "arbitrary_precision"))] 637 | { 638 | N::PosInt(u) 639 | } 640 | #[cfg(feature = "arbitrary_precision")] 641 | { 642 | u.to_string() 643 | } 644 | } 645 | ParserNumber::I64(i) => { 646 | #[cfg(not(feature = "arbitrary_precision"))] 647 | { 648 | N::NegInt(i) 649 | } 650 | #[cfg(feature = "arbitrary_precision")] 651 | { 652 | i.to_string() 653 | } 654 | } 655 | #[cfg(feature = "arbitrary_precision")] 656 | ParserNumber::String(s) => s, 657 | }; 658 | Number { n: n } 659 | } 660 | } 661 | 662 | macro_rules! impl_from_unsigned { 663 | ( 664 | $($ty:ty),* 665 | ) => { 666 | $( 667 | impl From<$ty> for Number { 668 | #[inline] 669 | fn from(u: $ty) -> Self { 670 | let n = { 671 | #[cfg(not(feature = "arbitrary_precision"))] 672 | { N::PosInt(u as u64) } 673 | #[cfg(feature = "arbitrary_precision")] 674 | { 675 | itoa::Buffer::new().format(u).to_owned() 676 | } 677 | }; 678 | Number { n: n } 679 | } 680 | } 681 | )* 682 | }; 683 | } 684 | 685 | macro_rules! impl_from_signed { 686 | ( 687 | $($ty:ty),* 688 | ) => { 689 | $( 690 | impl From<$ty> for Number { 691 | #[inline] 692 | fn from(i: $ty) -> Self { 693 | let n = { 694 | #[cfg(not(feature = "arbitrary_precision"))] 695 | { 696 | if i < 0 { 697 | N::NegInt(i as i64) 698 | } else { 699 | N::PosInt(i as u64) 700 | } 701 | } 702 | #[cfg(feature = "arbitrary_precision")] 703 | { 704 | itoa::Buffer::new().format(i).to_owned() 705 | } 706 | }; 707 | Number { n: n } 708 | } 709 | } 710 | )* 711 | }; 712 | } 713 | 714 | impl_from_unsigned!(u8, u16, u32, u64, usize); 715 | impl_from_signed!(i8, i16, i32, i64, isize); 716 | 717 | #[cfg(feature = "arbitrary_precision")] 718 | serde_if_integer128! { 719 | impl From for Number { 720 | fn from(i: i128) -> Self { 721 | Number { n: i.to_string() } 722 | } 723 | } 724 | 725 | impl From for Number { 726 | fn from(u: u128) -> Self { 727 | Number { n: u.to_string() } 728 | } 729 | } 730 | } 731 | 732 | impl Number { 733 | #[cfg(not(feature = "arbitrary_precision"))] 734 | // Not public API. Should be pub(crate). 735 | #[doc(hidden)] 736 | #[cold] 737 | pub fn unexpected(&self) -> Unexpected { 738 | match self.n { 739 | N::PosInt(u) => Unexpected::Unsigned(u), 740 | N::NegInt(i) => Unexpected::Signed(i), 741 | N::Float(f) => Unexpected::Float(f), 742 | } 743 | } 744 | 745 | #[cfg(feature = "arbitrary_precision")] 746 | // Not public API. Should be pub(crate). 747 | #[doc(hidden)] 748 | #[cold] 749 | pub fn unexpected(&self) -> Unexpected { 750 | Unexpected::Other("number") 751 | } 752 | } 753 | -------------------------------------------------------------------------------- /src/map.rs: -------------------------------------------------------------------------------- 1 | //! A map of String to serde_json::Value. 2 | //! 3 | //! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order` 4 | //! feature of serde_json to use [`IndexMap`] instead. 5 | //! 6 | //! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html 7 | //! [`IndexMap`]: https://docs.rs/indexmap/*/indexmap/map/struct.IndexMap.html 8 | 9 | use serde::{de, ser}; 10 | use std::borrow::Borrow; 11 | use std::fmt::{self, Debug}; 12 | use std::hash::Hash; 13 | use std::iter::FromIterator; 14 | use std::ops; 15 | use value::Value; 16 | 17 | #[cfg(not(feature = "preserve_order"))] 18 | use std::collections::{btree_map, BTreeMap}; 19 | 20 | #[cfg(feature = "preserve_order")] 21 | use indexmap::{self, IndexMap}; 22 | 23 | /// Represents a JSON key/value type. 24 | pub struct Map { 25 | map: MapImpl, 26 | } 27 | 28 | #[cfg(not(feature = "preserve_order"))] 29 | type MapImpl = BTreeMap; 30 | #[cfg(feature = "preserve_order")] 31 | type MapImpl = IndexMap; 32 | 33 | impl Map { 34 | /// Makes a new empty Map. 35 | #[inline] 36 | pub fn new() -> Self { 37 | Map { 38 | map: MapImpl::new(), 39 | } 40 | } 41 | 42 | #[cfg(not(feature = "preserve_order"))] 43 | /// Makes a new empty Map with the given initial capacity. 44 | #[inline] 45 | pub fn with_capacity(capacity: usize) -> Self { 46 | // does not support with_capacity 47 | let _ = capacity; 48 | Map { 49 | map: BTreeMap::new(), 50 | } 51 | } 52 | 53 | #[cfg(feature = "preserve_order")] 54 | /// Makes a new empty Map with the given initial capacity. 55 | #[inline] 56 | pub fn with_capacity(capacity: usize) -> Self { 57 | Map { 58 | map: IndexMap::with_capacity(capacity), 59 | } 60 | } 61 | 62 | /// Clears the map, removing all values. 63 | #[inline] 64 | pub fn clear(&mut self) { 65 | self.map.clear() 66 | } 67 | 68 | /// Returns a reference to the value corresponding to the key. 69 | /// 70 | /// The key may be any borrowed form of the map's key type, but the ordering 71 | /// on the borrowed form *must* match the ordering on the key type. 72 | #[inline] 73 | pub fn get(&self, key: &Q) -> Option<&Value> 74 | where 75 | String: Borrow, 76 | Q: Ord + Eq + Hash, 77 | { 78 | self.map.get(key) 79 | } 80 | 81 | /// Returns true if the map contains a value for the specified key. 82 | /// 83 | /// The key may be any borrowed form of the map's key type, but the ordering 84 | /// on the borrowed form *must* match the ordering on the key type. 85 | #[inline] 86 | pub fn contains_key(&self, key: &Q) -> bool 87 | where 88 | String: Borrow, 89 | Q: Ord + Eq + Hash, 90 | { 91 | self.map.contains_key(key) 92 | } 93 | 94 | /// Returns a mutable reference to the value corresponding to the key. 95 | /// 96 | /// The key may be any borrowed form of the map's key type, but the ordering 97 | /// on the borrowed form *must* match the ordering on the key type. 98 | #[inline] 99 | pub fn get_mut(&mut self, key: &Q) -> Option<&mut Value> 100 | where 101 | String: Borrow, 102 | Q: Ord + Eq + Hash, 103 | { 104 | self.map.get_mut(key) 105 | } 106 | 107 | /// Inserts a key-value pair into the map. 108 | /// 109 | /// If the map did not have this key present, `None` is returned. 110 | /// 111 | /// If the map did have this key present, the value is updated, and the old 112 | /// value is returned. 113 | #[inline] 114 | pub fn insert(&mut self, k: String, v: Value) -> Option { 115 | self.map.insert(k, v) 116 | } 117 | 118 | /// Removes a key from the map, returning the value at the key if the key 119 | /// was previously in the map. 120 | /// 121 | /// The key may be any borrowed form of the map's key type, but the ordering 122 | /// on the borrowed form *must* match the ordering on the key type. 123 | #[inline] 124 | pub fn remove(&mut self, key: &Q) -> Option 125 | where 126 | String: Borrow, 127 | Q: Ord + Eq + Hash, 128 | { 129 | #[cfg(feature = "preserve_order")] 130 | return self.map.swap_remove(key); 131 | #[cfg(not(feature = "preserve_order"))] 132 | return self.map.remove(key); 133 | } 134 | 135 | /// Gets the given key's corresponding entry in the map for in-place 136 | /// manipulation. 137 | pub fn entry(&mut self, key: S) -> Entry 138 | where 139 | S: Into, 140 | { 141 | #[cfg(feature = "preserve_order")] 142 | use indexmap::map::Entry as EntryImpl; 143 | #[cfg(not(feature = "preserve_order"))] 144 | use std::collections::btree_map::Entry as EntryImpl; 145 | 146 | match self.map.entry(key.into()) { 147 | EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }), 148 | EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied: occupied }), 149 | } 150 | } 151 | 152 | /// Returns the number of elements in the map. 153 | #[inline] 154 | pub fn len(&self) -> usize { 155 | self.map.len() 156 | } 157 | 158 | /// Returns true if the map contains no elements. 159 | #[inline] 160 | pub fn is_empty(&self) -> bool { 161 | self.map.is_empty() 162 | } 163 | 164 | /// Gets an iterator over the entries of the map. 165 | #[inline] 166 | pub fn iter(&self) -> Iter { 167 | Iter { 168 | iter: self.map.iter(), 169 | } 170 | } 171 | 172 | /// Gets a mutable iterator over the entries of the map. 173 | #[inline] 174 | pub fn iter_mut(&mut self) -> IterMut { 175 | IterMut { 176 | iter: self.map.iter_mut(), 177 | } 178 | } 179 | 180 | /// Gets an iterator over the keys of the map. 181 | #[inline] 182 | pub fn keys(&self) -> Keys { 183 | Keys { 184 | iter: self.map.keys(), 185 | } 186 | } 187 | 188 | /// Gets an iterator over the values of the map. 189 | #[inline] 190 | pub fn values(&self) -> Values { 191 | Values { 192 | iter: self.map.values(), 193 | } 194 | } 195 | 196 | /// Gets an iterator over mutable values of the map. 197 | #[inline] 198 | pub fn values_mut(&mut self) -> ValuesMut { 199 | ValuesMut { 200 | iter: self.map.values_mut(), 201 | } 202 | } 203 | } 204 | 205 | impl Default for Map { 206 | #[inline] 207 | fn default() -> Self { 208 | Map { 209 | map: MapImpl::new(), 210 | } 211 | } 212 | } 213 | 214 | impl Clone for Map { 215 | #[inline] 216 | fn clone(&self) -> Self { 217 | Map { 218 | map: self.map.clone(), 219 | } 220 | } 221 | } 222 | 223 | impl PartialEq for Map { 224 | #[inline] 225 | fn eq(&self, other: &Self) -> bool { 226 | if cfg!(feature = "preserve_order") { 227 | if self.len() != other.len() { 228 | return false; 229 | } 230 | 231 | self.iter() 232 | .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) 233 | } else { 234 | self.map.eq(&other.map) 235 | } 236 | } 237 | } 238 | 239 | /// Access an element of this map. Panics if the given key is not present in the 240 | /// map. 241 | /// 242 | /// ```edition2018 243 | /// # use serde_json::Value; 244 | /// # 245 | /// # let val = &Value::String("".to_owned()); 246 | /// # let _ = 247 | /// match *val { 248 | /// Value::String(ref s) => Some(s.as_str()), 249 | /// Value::Array(ref arr) => arr[0].as_str(), 250 | /// Value::Object(ref map) => map["type"].as_str(), 251 | /// _ => None, 252 | /// } 253 | /// # ; 254 | /// ``` 255 | impl<'a, Q: ?Sized> ops::Index<&'a Q> for Map 256 | where 257 | String: Borrow, 258 | Q: Ord + Eq + Hash, 259 | { 260 | type Output = Value; 261 | 262 | fn index(&self, index: &Q) -> &Value { 263 | self.map.index(index) 264 | } 265 | } 266 | 267 | /// Mutably access an element of this map. Panics if the given key is not 268 | /// present in the map. 269 | /// 270 | /// ```edition2018 271 | /// # use serde_json::json; 272 | /// # 273 | /// # let mut map = serde_json::Map::new(); 274 | /// # map.insert("key".to_owned(), serde_json::Value::Null); 275 | /// # 276 | /// map["key"] = json!("value"); 277 | /// ``` 278 | impl<'a, Q: ?Sized> ops::IndexMut<&'a Q> for Map 279 | where 280 | String: Borrow, 281 | Q: Ord + Eq + Hash, 282 | { 283 | fn index_mut(&mut self, index: &Q) -> &mut Value { 284 | self.map.get_mut(index).expect("no entry found for key") 285 | } 286 | } 287 | 288 | impl Debug for Map { 289 | #[inline] 290 | fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { 291 | self.map.fmt(formatter) 292 | } 293 | } 294 | 295 | impl ser::Serialize for Map { 296 | #[inline] 297 | fn serialize(&self, serializer: S) -> Result 298 | where 299 | S: ser::Serializer, 300 | { 301 | use serde::ser::SerializeMap; 302 | let mut map = try!(serializer.serialize_map(Some(self.len()))); 303 | for (k, v) in self { 304 | try!(map.serialize_key(k)); 305 | try!(map.serialize_value(v)); 306 | } 307 | map.end() 308 | } 309 | } 310 | 311 | impl<'de> de::Deserialize<'de> for Map { 312 | #[inline] 313 | fn deserialize(deserializer: D) -> Result 314 | where 315 | D: de::Deserializer<'de>, 316 | { 317 | struct Visitor; 318 | 319 | impl<'de> de::Visitor<'de> for Visitor { 320 | type Value = Map; 321 | 322 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 323 | formatter.write_str("a map") 324 | } 325 | 326 | #[inline] 327 | fn visit_unit(self) -> Result 328 | where 329 | E: de::Error, 330 | { 331 | Ok(Map::new()) 332 | } 333 | 334 | #[inline] 335 | fn visit_map(self, mut visitor: V) -> Result 336 | where 337 | V: de::MapAccess<'de>, 338 | { 339 | let mut values = Map::new(); 340 | 341 | while let Some((key, value)) = try!(visitor.next_entry()) { 342 | values.insert(key, value); 343 | } 344 | 345 | Ok(values) 346 | } 347 | } 348 | 349 | deserializer.deserialize_map(Visitor) 350 | } 351 | } 352 | 353 | impl FromIterator<(String, Value)> for Map { 354 | fn from_iter(iter: T) -> Self 355 | where 356 | T: IntoIterator, 357 | { 358 | Map { 359 | map: FromIterator::from_iter(iter), 360 | } 361 | } 362 | } 363 | 364 | impl Extend<(String, Value)> for Map { 365 | fn extend(&mut self, iter: T) 366 | where 367 | T: IntoIterator, 368 | { 369 | self.map.extend(iter); 370 | } 371 | } 372 | 373 | macro_rules! delegate_iterator { 374 | (($name:ident $($generics:tt)*) => $item:ty) => { 375 | impl $($generics)* Iterator for $name $($generics)* { 376 | type Item = $item; 377 | #[inline] 378 | fn next(&mut self) -> Option { 379 | self.iter.next() 380 | } 381 | #[inline] 382 | fn size_hint(&self) -> (usize, Option) { 383 | self.iter.size_hint() 384 | } 385 | } 386 | 387 | impl $($generics)* DoubleEndedIterator for $name $($generics)* { 388 | #[inline] 389 | fn next_back(&mut self) -> Option { 390 | self.iter.next_back() 391 | } 392 | } 393 | 394 | impl $($generics)* ExactSizeIterator for $name $($generics)* { 395 | #[inline] 396 | fn len(&self) -> usize { 397 | self.iter.len() 398 | } 399 | } 400 | } 401 | } 402 | 403 | ////////////////////////////////////////////////////////////////////////////// 404 | 405 | /// A view into a single entry in a map, which may either be vacant or occupied. 406 | /// This enum is constructed from the [`entry`] method on [`Map`]. 407 | /// 408 | /// [`entry`]: struct.Map.html#method.entry 409 | /// [`Map`]: struct.Map.html 410 | pub enum Entry<'a> { 411 | /// A vacant Entry. 412 | Vacant(VacantEntry<'a>), 413 | /// An occupied Entry. 414 | Occupied(OccupiedEntry<'a>), 415 | } 416 | 417 | /// A vacant Entry. It is part of the [`Entry`] enum. 418 | /// 419 | /// [`Entry`]: enum.Entry.html 420 | pub struct VacantEntry<'a> { 421 | vacant: VacantEntryImpl<'a>, 422 | } 423 | 424 | /// An occupied Entry. It is part of the [`Entry`] enum. 425 | /// 426 | /// [`Entry`]: enum.Entry.html 427 | pub struct OccupiedEntry<'a> { 428 | occupied: OccupiedEntryImpl<'a>, 429 | } 430 | 431 | #[cfg(not(feature = "preserve_order"))] 432 | type VacantEntryImpl<'a> = btree_map::VacantEntry<'a, String, Value>; 433 | #[cfg(feature = "preserve_order")] 434 | type VacantEntryImpl<'a> = indexmap::map::VacantEntry<'a, String, Value>; 435 | 436 | #[cfg(not(feature = "preserve_order"))] 437 | type OccupiedEntryImpl<'a> = btree_map::OccupiedEntry<'a, String, Value>; 438 | #[cfg(feature = "preserve_order")] 439 | type OccupiedEntryImpl<'a> = indexmap::map::OccupiedEntry<'a, String, Value>; 440 | 441 | impl<'a> Entry<'a> { 442 | /// Returns a reference to this entry's key. 443 | /// 444 | /// # Examples 445 | /// 446 | /// ```edition2018 447 | /// let mut map = serde_json::Map::new(); 448 | /// assert_eq!(map.entry("serde").key(), &"serde"); 449 | /// ``` 450 | pub fn key(&self) -> &String { 451 | match *self { 452 | Entry::Vacant(ref e) => e.key(), 453 | Entry::Occupied(ref e) => e.key(), 454 | } 455 | } 456 | 457 | /// Ensures a value is in the entry by inserting the default if empty, and 458 | /// returns a mutable reference to the value in the entry. 459 | /// 460 | /// # Examples 461 | /// 462 | /// ```edition2018 463 | /// # use serde_json::json; 464 | /// # 465 | /// let mut map = serde_json::Map::new(); 466 | /// map.entry("serde").or_insert(json!(12)); 467 | /// 468 | /// assert_eq!(map["serde"], 12); 469 | /// ``` 470 | pub fn or_insert(self, default: Value) -> &'a mut Value { 471 | match self { 472 | Entry::Vacant(entry) => entry.insert(default), 473 | Entry::Occupied(entry) => entry.into_mut(), 474 | } 475 | } 476 | 477 | /// Ensures a value is in the entry by inserting the result of the default 478 | /// function if empty, and returns a mutable reference to the value in the 479 | /// entry. 480 | /// 481 | /// # Examples 482 | /// 483 | /// ```edition2018 484 | /// # use serde_json::json; 485 | /// # 486 | /// let mut map = serde_json::Map::new(); 487 | /// map.entry("serde").or_insert_with(|| json!("hoho")); 488 | /// 489 | /// assert_eq!(map["serde"], "hoho".to_owned()); 490 | /// ``` 491 | pub fn or_insert_with(self, default: F) -> &'a mut Value 492 | where 493 | F: FnOnce() -> Value, 494 | { 495 | match self { 496 | Entry::Vacant(entry) => entry.insert(default()), 497 | Entry::Occupied(entry) => entry.into_mut(), 498 | } 499 | } 500 | } 501 | 502 | impl<'a> VacantEntry<'a> { 503 | /// Gets a reference to the key that would be used when inserting a value 504 | /// through the VacantEntry. 505 | /// 506 | /// # Examples 507 | /// 508 | /// ```edition2018 509 | /// use serde_json::map::Entry; 510 | /// 511 | /// let mut map = serde_json::Map::new(); 512 | /// 513 | /// match map.entry("serde") { 514 | /// Entry::Vacant(vacant) => { 515 | /// assert_eq!(vacant.key(), &"serde"); 516 | /// } 517 | /// Entry::Occupied(_) => unimplemented!(), 518 | /// } 519 | /// ``` 520 | #[inline] 521 | pub fn key(&self) -> &String { 522 | self.vacant.key() 523 | } 524 | 525 | /// Sets the value of the entry with the VacantEntry's key, and returns a 526 | /// mutable reference to it. 527 | /// 528 | /// # Examples 529 | /// 530 | /// ```edition2018 531 | /// # use serde_json::json; 532 | /// # 533 | /// use serde_json::map::Entry; 534 | /// 535 | /// let mut map = serde_json::Map::new(); 536 | /// 537 | /// match map.entry("serde") { 538 | /// Entry::Vacant(vacant) => { 539 | /// vacant.insert(json!("hoho")); 540 | /// } 541 | /// Entry::Occupied(_) => unimplemented!(), 542 | /// } 543 | /// ``` 544 | #[inline] 545 | pub fn insert(self, value: Value) -> &'a mut Value { 546 | self.vacant.insert(value) 547 | } 548 | } 549 | 550 | impl<'a> OccupiedEntry<'a> { 551 | /// Gets a reference to the key in the entry. 552 | /// 553 | /// # Examples 554 | /// 555 | /// ```edition2018 556 | /// # use serde_json::json; 557 | /// # 558 | /// use serde_json::map::Entry; 559 | /// 560 | /// let mut map = serde_json::Map::new(); 561 | /// map.insert("serde".to_owned(), json!(12)); 562 | /// 563 | /// match map.entry("serde") { 564 | /// Entry::Occupied(occupied) => { 565 | /// assert_eq!(occupied.key(), &"serde"); 566 | /// } 567 | /// Entry::Vacant(_) => unimplemented!(), 568 | /// } 569 | /// ``` 570 | #[inline] 571 | pub fn key(&self) -> &String { 572 | self.occupied.key() 573 | } 574 | 575 | /// Gets a reference to the value in the entry. 576 | /// 577 | /// # Examples 578 | /// 579 | /// ```edition2018 580 | /// # use serde_json::json; 581 | /// # 582 | /// use serde_json::map::Entry; 583 | /// 584 | /// let mut map = serde_json::Map::new(); 585 | /// map.insert("serde".to_owned(), json!(12)); 586 | /// 587 | /// match map.entry("serde") { 588 | /// Entry::Occupied(occupied) => { 589 | /// assert_eq!(occupied.get(), 12); 590 | /// } 591 | /// Entry::Vacant(_) => unimplemented!(), 592 | /// } 593 | /// ``` 594 | #[inline] 595 | pub fn get(&self) -> &Value { 596 | self.occupied.get() 597 | } 598 | 599 | /// Gets a mutable reference to the value in the entry. 600 | /// 601 | /// # Examples 602 | /// 603 | /// ```edition2018 604 | /// # use serde_json::json; 605 | /// # 606 | /// use serde_json::map::Entry; 607 | /// 608 | /// let mut map = serde_json::Map::new(); 609 | /// map.insert("serde".to_owned(), json!([1, 2, 3])); 610 | /// 611 | /// match map.entry("serde") { 612 | /// Entry::Occupied(mut occupied) => { 613 | /// occupied.get_mut().as_array_mut().unwrap().push(json!(4)); 614 | /// } 615 | /// Entry::Vacant(_) => unimplemented!(), 616 | /// } 617 | /// 618 | /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); 619 | /// ``` 620 | #[inline] 621 | pub fn get_mut(&mut self) -> &mut Value { 622 | self.occupied.get_mut() 623 | } 624 | 625 | /// Converts the entry into a mutable reference to its value. 626 | /// 627 | /// # Examples 628 | /// 629 | /// ```edition2018 630 | /// # use serde_json::json; 631 | /// # 632 | /// use serde_json::map::Entry; 633 | /// 634 | /// let mut map = serde_json::Map::new(); 635 | /// map.insert("serde".to_owned(), json!([1, 2, 3])); 636 | /// 637 | /// match map.entry("serde") { 638 | /// Entry::Occupied(mut occupied) => { 639 | /// occupied.into_mut().as_array_mut().unwrap().push(json!(4)); 640 | /// } 641 | /// Entry::Vacant(_) => unimplemented!(), 642 | /// } 643 | /// 644 | /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); 645 | /// ``` 646 | #[inline] 647 | pub fn into_mut(self) -> &'a mut Value { 648 | self.occupied.into_mut() 649 | } 650 | 651 | /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns 652 | /// the entry's old value. 653 | /// 654 | /// # Examples 655 | /// 656 | /// ```edition2018 657 | /// # use serde_json::json; 658 | /// # 659 | /// use serde_json::map::Entry; 660 | /// 661 | /// let mut map = serde_json::Map::new(); 662 | /// map.insert("serde".to_owned(), json!(12)); 663 | /// 664 | /// match map.entry("serde") { 665 | /// Entry::Occupied(mut occupied) => { 666 | /// assert_eq!(occupied.insert(json!(13)), 12); 667 | /// assert_eq!(occupied.get(), 13); 668 | /// } 669 | /// Entry::Vacant(_) => unimplemented!(), 670 | /// } 671 | /// ``` 672 | #[inline] 673 | pub fn insert(&mut self, value: Value) -> Value { 674 | self.occupied.insert(value) 675 | } 676 | 677 | /// Takes the value of the entry out of the map, and returns it. 678 | /// 679 | /// # Examples 680 | /// 681 | /// ```edition2018 682 | /// # use serde_json::json; 683 | /// # 684 | /// use serde_json::map::Entry; 685 | /// 686 | /// let mut map = serde_json::Map::new(); 687 | /// map.insert("serde".to_owned(), json!(12)); 688 | /// 689 | /// match map.entry("serde") { 690 | /// Entry::Occupied(occupied) => { 691 | /// assert_eq!(occupied.remove(), 12); 692 | /// } 693 | /// Entry::Vacant(_) => unimplemented!(), 694 | /// } 695 | /// ``` 696 | #[inline] 697 | pub fn remove(self) -> Value { 698 | #[cfg(feature = "preserve_order")] 699 | return self.occupied.swap_remove(); 700 | #[cfg(not(feature = "preserve_order"))] 701 | return self.occupied.remove(); 702 | } 703 | } 704 | 705 | ////////////////////////////////////////////////////////////////////////////// 706 | 707 | impl<'a> IntoIterator for &'a Map { 708 | type Item = (&'a String, &'a Value); 709 | type IntoIter = Iter<'a>; 710 | #[inline] 711 | fn into_iter(self) -> Self::IntoIter { 712 | Iter { 713 | iter: self.map.iter(), 714 | } 715 | } 716 | } 717 | 718 | /// An iterator over a serde_json::Map's entries. 719 | pub struct Iter<'a> { 720 | iter: IterImpl<'a>, 721 | } 722 | 723 | #[cfg(not(feature = "preserve_order"))] 724 | type IterImpl<'a> = btree_map::Iter<'a, String, Value>; 725 | #[cfg(feature = "preserve_order")] 726 | type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>; 727 | 728 | delegate_iterator!((Iter<'a>) => (&'a String, &'a Value)); 729 | 730 | ////////////////////////////////////////////////////////////////////////////// 731 | 732 | impl<'a> IntoIterator for &'a mut Map { 733 | type Item = (&'a String, &'a mut Value); 734 | type IntoIter = IterMut<'a>; 735 | #[inline] 736 | fn into_iter(self) -> Self::IntoIter { 737 | IterMut { 738 | iter: self.map.iter_mut(), 739 | } 740 | } 741 | } 742 | 743 | /// A mutable iterator over a serde_json::Map's entries. 744 | pub struct IterMut<'a> { 745 | iter: IterMutImpl<'a>, 746 | } 747 | 748 | #[cfg(not(feature = "preserve_order"))] 749 | type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>; 750 | #[cfg(feature = "preserve_order")] 751 | type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>; 752 | 753 | delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value)); 754 | 755 | ////////////////////////////////////////////////////////////////////////////// 756 | 757 | impl IntoIterator for Map { 758 | type Item = (String, Value); 759 | type IntoIter = IntoIter; 760 | #[inline] 761 | fn into_iter(self) -> Self::IntoIter { 762 | IntoIter { 763 | iter: self.map.into_iter(), 764 | } 765 | } 766 | } 767 | 768 | /// An owning iterator over a serde_json::Map's entries. 769 | pub struct IntoIter { 770 | iter: IntoIterImpl, 771 | } 772 | 773 | #[cfg(not(feature = "preserve_order"))] 774 | type IntoIterImpl = btree_map::IntoIter; 775 | #[cfg(feature = "preserve_order")] 776 | type IntoIterImpl = indexmap::map::IntoIter; 777 | 778 | delegate_iterator!((IntoIter) => (String, Value)); 779 | 780 | ////////////////////////////////////////////////////////////////////////////// 781 | 782 | /// An iterator over a serde_json::Map's keys. 783 | pub struct Keys<'a> { 784 | iter: KeysImpl<'a>, 785 | } 786 | 787 | #[cfg(not(feature = "preserve_order"))] 788 | type KeysImpl<'a> = btree_map::Keys<'a, String, Value>; 789 | #[cfg(feature = "preserve_order")] 790 | type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>; 791 | 792 | delegate_iterator!((Keys<'a>) => &'a String); 793 | 794 | ////////////////////////////////////////////////////////////////////////////// 795 | 796 | /// An iterator over a serde_json::Map's values. 797 | pub struct Values<'a> { 798 | iter: ValuesImpl<'a>, 799 | } 800 | 801 | #[cfg(not(feature = "preserve_order"))] 802 | type ValuesImpl<'a> = btree_map::Values<'a, String, Value>; 803 | #[cfg(feature = "preserve_order")] 804 | type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>; 805 | 806 | delegate_iterator!((Values<'a>) => &'a Value); 807 | 808 | ////////////////////////////////////////////////////////////////////////////// 809 | 810 | /// A mutable iterator over a serde_json::Map's values. 811 | pub struct ValuesMut<'a> { 812 | iter: ValuesMutImpl<'a>, 813 | } 814 | 815 | #[cfg(not(feature = "preserve_order"))] 816 | type ValuesMutImpl<'a> = btree_map::ValuesMut<'a, String, Value>; 817 | #[cfg(feature = "preserve_order")] 818 | type ValuesMutImpl<'a> = indexmap::map::ValuesMut<'a, String, Value>; 819 | 820 | delegate_iterator!((ValuesMut<'a>) => &'a mut Value); 821 | -------------------------------------------------------------------------------- /src/read.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Deref; 2 | use std::{char, cmp, io, str}; 3 | 4 | #[cfg(feature = "raw_value")] 5 | use serde::de::Visitor; 6 | 7 | use iter::LineColIterator; 8 | 9 | use error::{Error, ErrorCode, Result}; 10 | 11 | #[cfg(feature = "raw_value")] 12 | use raw::{BorrowedRawDeserializer, OwnedRawDeserializer}; 13 | 14 | /// Trait used by the deserializer for iterating over input. This is manually 15 | /// "specialized" for iterating over &[u8]. Once feature(specialization) is 16 | /// stable we can use actual specialization. 17 | /// 18 | /// This trait is sealed and cannot be implemented for types outside of 19 | /// `serde_json`. 20 | pub trait Read<'de>: private::Sealed { 21 | #[doc(hidden)] 22 | fn next(&mut self) -> Result>; 23 | #[doc(hidden)] 24 | fn peek(&mut self) -> Result>; 25 | 26 | /// Only valid after a call to peek(). Discards the peeked byte. 27 | #[doc(hidden)] 28 | fn discard(&mut self); 29 | 30 | /// Position of the most recent call to next(). 31 | /// 32 | /// The most recent call was probably next() and not peek(), but this method 33 | /// should try to return a sensible result if the most recent call was 34 | /// actually peek() because we don't always know. 35 | /// 36 | /// Only called in case of an error, so performance is not important. 37 | #[doc(hidden)] 38 | fn position(&self) -> Position; 39 | 40 | /// Position of the most recent call to peek(). 41 | /// 42 | /// The most recent call was probably peek() and not next(), but this method 43 | /// should try to return a sensible result if the most recent call was 44 | /// actually next() because we don't always know. 45 | /// 46 | /// Only called in case of an error, so performance is not important. 47 | #[doc(hidden)] 48 | fn peek_position(&self) -> Position; 49 | 50 | /// Offset from the beginning of the input to the next byte that would be 51 | /// returned by next() or peek(). 52 | #[doc(hidden)] 53 | fn byte_offset(&self) -> usize; 54 | 55 | /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped 56 | /// string until the next quotation mark using the given scratch space if 57 | /// necessary. The scratch space is initially empty. 58 | #[doc(hidden)] 59 | fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result>; 60 | 61 | /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped 62 | /// string until the next quotation mark using the given scratch space if 63 | /// necessary. The scratch space is initially empty. 64 | /// 65 | /// This function returns the raw bytes in the string with escape sequences 66 | /// expanded but without performing unicode validation. 67 | #[doc(hidden)] 68 | fn parse_str_raw<'s>( 69 | &'s mut self, 70 | scratch: &'s mut Vec, 71 | ) -> Result>; 72 | 73 | /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped 74 | /// string until the next quotation mark but discards the data. 75 | #[doc(hidden)] 76 | fn ignore_str(&mut self) -> Result<()>; 77 | 78 | /// Assumes the previous byte was a hex escape sequnce ('\u') in a string. 79 | /// Parses next hexadecimal sequence. 80 | #[doc(hidden)] 81 | fn decode_hex_escape(&mut self) -> Result; 82 | 83 | /// Switch raw buffering mode on. 84 | /// 85 | /// This is used when deserializing `RawValue`. 86 | #[cfg(feature = "raw_value")] 87 | #[doc(hidden)] 88 | fn begin_raw_buffering(&mut self); 89 | 90 | /// Switch raw buffering mode off and provides the raw buffered data to the 91 | /// given visitor. 92 | #[cfg(feature = "raw_value")] 93 | #[doc(hidden)] 94 | fn end_raw_buffering(&mut self, visitor: V) -> Result 95 | where 96 | V: Visitor<'de>; 97 | } 98 | 99 | pub struct Position { 100 | pub line: usize, 101 | pub column: usize, 102 | } 103 | 104 | pub enum Reference<'b, 'c, T: ?Sized + 'static> { 105 | Borrowed(&'b T), 106 | Copied(&'c T), 107 | } 108 | 109 | impl<'b, 'c, T: ?Sized + 'static> Deref for Reference<'b, 'c, T> { 110 | type Target = T; 111 | 112 | fn deref(&self) -> &Self::Target { 113 | match *self { 114 | Reference::Borrowed(b) => b, 115 | Reference::Copied(c) => c, 116 | } 117 | } 118 | } 119 | 120 | /// JSON input source that reads from a std::io input stream. 121 | pub struct IoRead 122 | where 123 | R: io::Read, 124 | { 125 | iter: LineColIterator>, 126 | /// Temporary storage of peeked byte. 127 | ch: Option, 128 | #[cfg(feature = "raw_value")] 129 | raw_buffer: Option>, 130 | } 131 | 132 | /// JSON input source that reads from a slice of bytes. 133 | // 134 | // This is more efficient than other iterators because peek() can be read-only 135 | // and we can compute line/col position only if an error happens. 136 | pub struct SliceRead<'a> { 137 | slice: &'a [u8], 138 | /// Index of the *next* byte that will be returned by next() or peek(). 139 | index: usize, 140 | #[cfg(feature = "raw_value")] 141 | raw_buffering_start_index: usize, 142 | } 143 | 144 | /// JSON input source that reads from a UTF-8 string. 145 | // 146 | // Able to elide UTF-8 checks by assuming that the input is valid UTF-8. 147 | pub struct StrRead<'a> { 148 | delegate: SliceRead<'a>, 149 | #[cfg(feature = "raw_value")] 150 | data: &'a str, 151 | } 152 | 153 | // Prevent users from implementing the Read trait. 154 | mod private { 155 | pub trait Sealed {} 156 | } 157 | 158 | ////////////////////////////////////////////////////////////////////////////// 159 | 160 | impl IoRead 161 | where 162 | R: io::Read, 163 | { 164 | /// Create a JSON input source to read from a std::io input stream. 165 | pub fn new(reader: R) -> Self { 166 | #[cfg(not(feature = "raw_value"))] 167 | { 168 | IoRead { 169 | iter: LineColIterator::new(reader.bytes()), 170 | ch: None, 171 | } 172 | } 173 | #[cfg(feature = "raw_value")] 174 | { 175 | IoRead { 176 | iter: LineColIterator::new(reader.bytes()), 177 | ch: None, 178 | raw_buffer: None, 179 | } 180 | } 181 | } 182 | } 183 | 184 | impl private::Sealed for IoRead where R: io::Read {} 185 | 186 | impl IoRead 187 | where 188 | R: io::Read, 189 | { 190 | fn parse_str_bytes<'s, T, F>( 191 | &'s mut self, 192 | scratch: &'s mut Vec, 193 | validate: bool, 194 | result: F, 195 | ) -> Result 196 | where 197 | T: 's, 198 | F: FnOnce(&'s Self, &'s [u8]) -> Result, 199 | { 200 | loop { 201 | let ch = try!(next_or_eof(self)); 202 | if !ESCAPE[ch as usize] { 203 | scratch.push(ch); 204 | continue; 205 | } 206 | match ch { 207 | b'"' => { 208 | return result(self, scratch); 209 | } 210 | b'\\' => { 211 | try!(parse_escape(self, scratch)); 212 | } 213 | _ => { 214 | if validate { 215 | return error(self, ErrorCode::ControlCharacterWhileParsingString); 216 | } 217 | scratch.push(ch); 218 | } 219 | } 220 | } 221 | } 222 | } 223 | 224 | impl<'de, R> Read<'de> for IoRead 225 | where 226 | R: io::Read, 227 | { 228 | #[inline] 229 | fn next(&mut self) -> Result> { 230 | match self.ch.take() { 231 | Some(ch) => { 232 | #[cfg(feature = "raw_value")] 233 | { 234 | if let Some(ref mut buf) = self.raw_buffer { 235 | buf.push(ch); 236 | } 237 | } 238 | Ok(Some(ch)) 239 | } 240 | None => match self.iter.next() { 241 | Some(Err(err)) => Err(Error::io(err)), 242 | Some(Ok(ch)) => { 243 | #[cfg(feature = "raw_value")] 244 | { 245 | if let Some(ref mut buf) = self.raw_buffer { 246 | buf.push(ch); 247 | } 248 | } 249 | Ok(Some(ch)) 250 | } 251 | None => Ok(None), 252 | }, 253 | } 254 | } 255 | 256 | #[inline] 257 | fn peek(&mut self) -> Result> { 258 | match self.ch { 259 | Some(ch) => Ok(Some(ch)), 260 | None => match self.iter.next() { 261 | Some(Err(err)) => Err(Error::io(err)), 262 | Some(Ok(ch)) => { 263 | self.ch = Some(ch); 264 | Ok(self.ch) 265 | } 266 | None => Ok(None), 267 | }, 268 | } 269 | } 270 | 271 | #[cfg(not(feature = "raw_value"))] 272 | #[inline] 273 | fn discard(&mut self) { 274 | self.ch = None; 275 | } 276 | 277 | #[cfg(feature = "raw_value")] 278 | fn discard(&mut self) { 279 | if let Some(ch) = self.ch.take() { 280 | if let Some(ref mut buf) = self.raw_buffer { 281 | buf.push(ch); 282 | } 283 | } 284 | } 285 | 286 | fn position(&self) -> Position { 287 | Position { 288 | line: self.iter.line(), 289 | column: self.iter.col(), 290 | } 291 | } 292 | 293 | fn peek_position(&self) -> Position { 294 | // The LineColIterator updates its position during peek() so it has the 295 | // right one here. 296 | self.position() 297 | } 298 | 299 | fn byte_offset(&self) -> usize { 300 | match self.ch { 301 | Some(_) => self.iter.byte_offset() - 1, 302 | None => self.iter.byte_offset(), 303 | } 304 | } 305 | 306 | fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 307 | self.parse_str_bytes(scratch, true, as_str) 308 | .map(Reference::Copied) 309 | } 310 | 311 | fn parse_str_raw<'s>( 312 | &'s mut self, 313 | scratch: &'s mut Vec, 314 | ) -> Result> { 315 | self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) 316 | .map(Reference::Copied) 317 | } 318 | 319 | fn ignore_str(&mut self) -> Result<()> { 320 | loop { 321 | let ch = try!(next_or_eof(self)); 322 | if !ESCAPE[ch as usize] { 323 | continue; 324 | } 325 | match ch { 326 | b'"' => { 327 | return Ok(()); 328 | } 329 | b'\\' => { 330 | try!(ignore_escape(self)); 331 | } 332 | _ => { 333 | return error(self, ErrorCode::ControlCharacterWhileParsingString); 334 | } 335 | } 336 | } 337 | } 338 | 339 | fn decode_hex_escape(&mut self) -> Result { 340 | let mut n = 0; 341 | for _ in 0..4 { 342 | match decode_hex_val(try!(next_or_eof(self))) { 343 | None => return error(self, ErrorCode::InvalidEscape), 344 | Some(val) => { 345 | n = (n << 4) + val; 346 | } 347 | } 348 | } 349 | Ok(n) 350 | } 351 | 352 | #[cfg(feature = "raw_value")] 353 | fn begin_raw_buffering(&mut self) { 354 | self.raw_buffer = Some(Vec::new()); 355 | } 356 | 357 | #[cfg(feature = "raw_value")] 358 | fn end_raw_buffering(&mut self, visitor: V) -> Result 359 | where 360 | V: Visitor<'de>, 361 | { 362 | let raw = self.raw_buffer.take().unwrap(); 363 | let raw = String::from_utf8(raw).unwrap(); 364 | visitor.visit_map(OwnedRawDeserializer { 365 | raw_value: Some(raw), 366 | }) 367 | } 368 | } 369 | 370 | ////////////////////////////////////////////////////////////////////////////// 371 | 372 | impl<'a> SliceRead<'a> { 373 | /// Create a JSON input source to read from a slice of bytes. 374 | pub fn new(slice: &'a [u8]) -> Self { 375 | #[cfg(not(feature = "raw_value"))] 376 | { 377 | SliceRead { 378 | slice: slice, 379 | index: 0, 380 | } 381 | } 382 | #[cfg(feature = "raw_value")] 383 | { 384 | SliceRead { 385 | slice: slice, 386 | index: 0, 387 | raw_buffering_start_index: 0, 388 | } 389 | } 390 | } 391 | 392 | fn position_of_index(&self, i: usize) -> Position { 393 | let mut position = Position { line: 1, column: 0 }; 394 | for ch in &self.slice[..i] { 395 | match *ch { 396 | b'\n' => { 397 | position.line += 1; 398 | position.column = 0; 399 | } 400 | _ => { 401 | position.column += 1; 402 | } 403 | } 404 | } 405 | position 406 | } 407 | 408 | /// The big optimization here over IoRead is that if the string contains no 409 | /// backslash escape sequences, the returned &str is a slice of the raw JSON 410 | /// data so we avoid copying into the scratch space. 411 | fn parse_str_bytes<'s, T: ?Sized, F>( 412 | &'s mut self, 413 | scratch: &'s mut Vec, 414 | validate: bool, 415 | result: F, 416 | ) -> Result> 417 | where 418 | T: 's, 419 | F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>, 420 | { 421 | // Index of the first byte not yet copied into the scratch space. 422 | let mut start = self.index; 423 | 424 | loop { 425 | while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] { 426 | self.index += 1; 427 | } 428 | if self.index == self.slice.len() { 429 | return error(self, ErrorCode::EofWhileParsingString); 430 | } 431 | match self.slice[self.index] { 432 | b'"' => { 433 | if scratch.is_empty() { 434 | // Fast path: return a slice of the raw JSON without any 435 | // copying. 436 | let borrowed = &self.slice[start..self.index]; 437 | self.index += 1; 438 | return result(self, borrowed).map(Reference::Borrowed); 439 | } else { 440 | scratch.extend_from_slice(&self.slice[start..self.index]); 441 | self.index += 1; 442 | return result(self, scratch).map(Reference::Copied); 443 | } 444 | } 445 | b'\\' => { 446 | scratch.extend_from_slice(&self.slice[start..self.index]); 447 | self.index += 1; 448 | try!(parse_escape(self, scratch)); 449 | start = self.index; 450 | } 451 | _ => { 452 | self.index += 1; 453 | if validate { 454 | return error(self, ErrorCode::ControlCharacterWhileParsingString); 455 | } 456 | } 457 | } 458 | } 459 | } 460 | } 461 | 462 | impl<'a> private::Sealed for SliceRead<'a> {} 463 | 464 | impl<'a> Read<'a> for SliceRead<'a> { 465 | #[inline] 466 | fn next(&mut self) -> Result> { 467 | // `Ok(self.slice.get(self.index).map(|ch| { self.index += 1; *ch }))` 468 | // is about 10% slower. 469 | Ok(if self.index < self.slice.len() { 470 | let ch = self.slice[self.index]; 471 | self.index += 1; 472 | Some(ch) 473 | } else { 474 | None 475 | }) 476 | } 477 | 478 | #[inline] 479 | fn peek(&mut self) -> Result> { 480 | // `Ok(self.slice.get(self.index).map(|ch| *ch))` is about 10% slower 481 | // for some reason. 482 | Ok(if self.index < self.slice.len() { 483 | Some(self.slice[self.index]) 484 | } else { 485 | None 486 | }) 487 | } 488 | 489 | #[inline] 490 | fn discard(&mut self) { 491 | self.index += 1; 492 | } 493 | 494 | fn position(&self) -> Position { 495 | self.position_of_index(self.index) 496 | } 497 | 498 | fn peek_position(&self) -> Position { 499 | // Cap it at slice.len() just in case the most recent call was next() 500 | // and it returned the last byte. 501 | self.position_of_index(cmp::min(self.slice.len(), self.index + 1)) 502 | } 503 | 504 | fn byte_offset(&self) -> usize { 505 | self.index 506 | } 507 | 508 | fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 509 | self.parse_str_bytes(scratch, true, as_str) 510 | } 511 | 512 | fn parse_str_raw<'s>( 513 | &'s mut self, 514 | scratch: &'s mut Vec, 515 | ) -> Result> { 516 | self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) 517 | } 518 | 519 | fn ignore_str(&mut self) -> Result<()> { 520 | loop { 521 | while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] { 522 | self.index += 1; 523 | } 524 | if self.index == self.slice.len() { 525 | return error(self, ErrorCode::EofWhileParsingString); 526 | } 527 | match self.slice[self.index] { 528 | b'"' => { 529 | self.index += 1; 530 | return Ok(()); 531 | } 532 | b'\\' => { 533 | self.index += 1; 534 | try!(ignore_escape(self)); 535 | } 536 | _ => { 537 | return error(self, ErrorCode::ControlCharacterWhileParsingString); 538 | } 539 | } 540 | } 541 | } 542 | 543 | fn decode_hex_escape(&mut self) -> Result { 544 | if self.index + 4 > self.slice.len() { 545 | self.index = self.slice.len(); 546 | return error(self, ErrorCode::EofWhileParsingString); 547 | } 548 | 549 | let mut n = 0; 550 | for _ in 0..4 { 551 | let ch = decode_hex_val(self.slice[self.index]); 552 | self.index += 1; 553 | match ch { 554 | None => return error(self, ErrorCode::InvalidEscape), 555 | Some(val) => { 556 | n = (n << 4) + val; 557 | } 558 | } 559 | } 560 | Ok(n) 561 | } 562 | 563 | #[cfg(feature = "raw_value")] 564 | fn begin_raw_buffering(&mut self) { 565 | self.raw_buffering_start_index = self.index; 566 | } 567 | 568 | #[cfg(feature = "raw_value")] 569 | fn end_raw_buffering(&mut self, visitor: V) -> Result 570 | where 571 | V: Visitor<'a>, 572 | { 573 | let raw = &self.slice[self.raw_buffering_start_index..self.index]; 574 | let raw = str::from_utf8(raw).unwrap(); 575 | visitor.visit_map(BorrowedRawDeserializer { 576 | raw_value: Some(raw), 577 | }) 578 | } 579 | } 580 | 581 | ////////////////////////////////////////////////////////////////////////////// 582 | 583 | impl<'a> StrRead<'a> { 584 | /// Create a JSON input source to read from a UTF-8 string. 585 | pub fn new(s: &'a str) -> Self { 586 | #[cfg(not(feature = "raw_value"))] 587 | { 588 | StrRead { 589 | delegate: SliceRead::new(s.as_bytes()), 590 | } 591 | } 592 | #[cfg(feature = "raw_value")] 593 | { 594 | StrRead { 595 | delegate: SliceRead::new(s.as_bytes()), 596 | data: s, 597 | } 598 | } 599 | } 600 | } 601 | 602 | impl<'a> private::Sealed for StrRead<'a> {} 603 | 604 | impl<'a> Read<'a> for StrRead<'a> { 605 | #[inline] 606 | fn next(&mut self) -> Result> { 607 | self.delegate.next() 608 | } 609 | 610 | #[inline] 611 | fn peek(&mut self) -> Result> { 612 | self.delegate.peek() 613 | } 614 | 615 | #[inline] 616 | fn discard(&mut self) { 617 | self.delegate.discard(); 618 | } 619 | 620 | fn position(&self) -> Position { 621 | self.delegate.position() 622 | } 623 | 624 | fn peek_position(&self) -> Position { 625 | self.delegate.peek_position() 626 | } 627 | 628 | fn byte_offset(&self) -> usize { 629 | self.delegate.byte_offset() 630 | } 631 | 632 | fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 633 | self.delegate.parse_str_bytes(scratch, true, |_, bytes| { 634 | // The input is assumed to be valid UTF-8 and the \u-escapes are 635 | // checked along the way, so don't need to check here. 636 | Ok(unsafe { str::from_utf8_unchecked(bytes) }) 637 | }) 638 | } 639 | 640 | fn parse_str_raw<'s>( 641 | &'s mut self, 642 | scratch: &'s mut Vec, 643 | ) -> Result> { 644 | self.delegate.parse_str_raw(scratch) 645 | } 646 | 647 | fn ignore_str(&mut self) -> Result<()> { 648 | self.delegate.ignore_str() 649 | } 650 | 651 | fn decode_hex_escape(&mut self) -> Result { 652 | self.delegate.decode_hex_escape() 653 | } 654 | 655 | #[cfg(feature = "raw_value")] 656 | fn begin_raw_buffering(&mut self) { 657 | self.delegate.begin_raw_buffering() 658 | } 659 | 660 | #[cfg(feature = "raw_value")] 661 | fn end_raw_buffering(&mut self, visitor: V) -> Result 662 | where 663 | V: Visitor<'a>, 664 | { 665 | let raw = &self.data[self.delegate.raw_buffering_start_index..self.delegate.index]; 666 | visitor.visit_map(BorrowedRawDeserializer { 667 | raw_value: Some(raw), 668 | }) 669 | } 670 | } 671 | 672 | ////////////////////////////////////////////////////////////////////////////// 673 | 674 | // Lookup table of bytes that must be escaped. A value of true at index i means 675 | // that byte i requires an escape sequence in the input. 676 | static ESCAPE: [bool; 256] = { 677 | const CT: bool = true; // control character \x00...\x1F 678 | const QU: bool = true; // quote \x22 679 | const BS: bool = true; // backslash \x5C 680 | const __: bool = false; // allow unescaped 681 | [ 682 | // 1 2 3 4 5 6 7 8 9 A B C D E F 683 | CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 0 684 | CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 1 685 | __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 686 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3 687 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4 688 | __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5 689 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6 690 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 691 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 692 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 693 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A 694 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B 695 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C 696 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D 697 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E 698 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F 699 | ] 700 | }; 701 | 702 | fn next_or_eof<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result { 703 | match try!(read.next()) { 704 | Some(b) => Ok(b), 705 | None => error(read, ErrorCode::EofWhileParsingString), 706 | } 707 | } 708 | 709 | fn error<'de, R: ?Sized + Read<'de>, T>(read: &R, reason: ErrorCode) -> Result { 710 | let position = read.position(); 711 | Err(Error::syntax(reason, position.line, position.column)) 712 | } 713 | 714 | fn as_str<'de, 's, R: Read<'de>>(read: &R, slice: &'s [u8]) -> Result<&'s str> { 715 | str::from_utf8(slice).or_else(|_| error(read, ErrorCode::InvalidUnicodeCodePoint)) 716 | } 717 | 718 | /// Parses a JSON escape sequence and appends it into the scratch space. Assumes 719 | /// the previous byte read was a backslash. 720 | fn parse_escape<'de, R: Read<'de>>(read: &mut R, scratch: &mut Vec) -> Result<()> { 721 | let ch = try!(next_or_eof(read)); 722 | 723 | match ch { 724 | b'"' => scratch.push(b'"'), 725 | b'\\' => scratch.push(b'\\'), 726 | b'/' => scratch.push(b'/'), 727 | b'b' => scratch.push(b'\x08'), 728 | b'f' => scratch.push(b'\x0c'), 729 | b'n' => scratch.push(b'\n'), 730 | b'r' => scratch.push(b'\r'), 731 | b't' => scratch.push(b'\t'), 732 | b'u' => { 733 | let c = match try!(read.decode_hex_escape()) { 734 | 0xDC00...0xDFFF => { 735 | return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); 736 | } 737 | 738 | // Non-BMP characters are encoded as a sequence of 739 | // two hex escapes, representing UTF-16 surrogates. 740 | n1 @ 0xD800...0xDBFF => { 741 | if try!(next_or_eof(read)) != b'\\' { 742 | return error(read, ErrorCode::UnexpectedEndOfHexEscape); 743 | } 744 | if try!(next_or_eof(read)) != b'u' { 745 | return error(read, ErrorCode::UnexpectedEndOfHexEscape); 746 | } 747 | 748 | let n2 = try!(read.decode_hex_escape()); 749 | 750 | if n2 < 0xDC00 || n2 > 0xDFFF { 751 | return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); 752 | } 753 | 754 | let n = (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000; 755 | 756 | match char::from_u32(n) { 757 | Some(c) => c, 758 | None => { 759 | return error(read, ErrorCode::InvalidUnicodeCodePoint); 760 | } 761 | } 762 | } 763 | 764 | n => match char::from_u32(n as u32) { 765 | Some(c) => c, 766 | None => { 767 | return error(read, ErrorCode::InvalidUnicodeCodePoint); 768 | } 769 | }, 770 | }; 771 | 772 | scratch.extend_from_slice(c.encode_utf8(&mut [0_u8; 4]).as_bytes()); 773 | } 774 | _ => { 775 | return error(read, ErrorCode::InvalidEscape); 776 | } 777 | } 778 | 779 | Ok(()) 780 | } 781 | 782 | /// Parses a JSON escape sequence and discards the value. Assumes the previous 783 | /// byte read was a backslash. 784 | fn ignore_escape<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result<()> { 785 | let ch = try!(next_or_eof(read)); 786 | 787 | match ch { 788 | b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {} 789 | b'u' => { 790 | let n = match try!(read.decode_hex_escape()) { 791 | 0xDC00...0xDFFF => { 792 | return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); 793 | } 794 | 795 | // Non-BMP characters are encoded as a sequence of 796 | // two hex escapes, representing UTF-16 surrogates. 797 | n1 @ 0xD800...0xDBFF => { 798 | if try!(next_or_eof(read)) != b'\\' { 799 | return error(read, ErrorCode::UnexpectedEndOfHexEscape); 800 | } 801 | if try!(next_or_eof(read)) != b'u' { 802 | return error(read, ErrorCode::UnexpectedEndOfHexEscape); 803 | } 804 | 805 | let n2 = try!(read.decode_hex_escape()); 806 | 807 | if n2 < 0xDC00 || n2 > 0xDFFF { 808 | return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); 809 | } 810 | 811 | (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000 812 | } 813 | 814 | n => n as u32, 815 | }; 816 | 817 | if char::from_u32(n).is_none() { 818 | return error(read, ErrorCode::InvalidUnicodeCodePoint); 819 | } 820 | } 821 | _ => { 822 | return error(read, ErrorCode::InvalidEscape); 823 | } 824 | } 825 | 826 | Ok(()) 827 | } 828 | 829 | static HEX: [u8; 256] = { 830 | const __: u8 = 255; // not a hex digit 831 | [ 832 | // 1 2 3 4 5 6 7 8 9 A B C D E F 833 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0 834 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 1 835 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 836 | 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, __, __, __, __, __, __, // 3 837 | __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 4 838 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 5 839 | __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 6 840 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 841 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 842 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 843 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A 844 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B 845 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C 846 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D 847 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E 848 | __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F 849 | ] 850 | }; 851 | 852 | fn decode_hex_val(val: u8) -> Option { 853 | let n = HEX[val as usize] as u16; 854 | if n == 255 { 855 | None 856 | } else { 857 | Some(n) 858 | } 859 | } 860 | --------------------------------------------------------------------------------