├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .gitignore ├── src ├── wrap.rs ├── path.rs ├── lib.rs ├── ser.rs └── de.rs ├── LICENSE-MIT ├── Cargo.toml ├── tests ├── serialize.rs └── deserialize.rs ├── README.md └── LICENSE-APACHE /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: dtolnay 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /src/wrap.rs: -------------------------------------------------------------------------------- 1 | use crate::{Chain, Track}; 2 | 3 | // Wrapper that attaches context to a `Visitor`, `SeqAccess` or `EnumAccess`. 4 | pub struct Wrap<'a, 'b, X> { 5 | pub(crate) delegate: X, 6 | pub(crate) chain: &'a Chain<'a>, 7 | pub(crate) track: &'b Track, 8 | } 9 | 10 | // Wrapper that attaches context to a `VariantAccess`. 11 | pub struct WrapVariant<'a, 'b, X> { 12 | pub(crate) delegate: X, 13 | pub(crate) chain: Chain<'a>, 14 | pub(crate) track: &'b Track, 15 | } 16 | 17 | impl<'a, 'b, X> Wrap<'a, 'b, X> { 18 | pub(crate) fn new(delegate: X, chain: &'a Chain<'a>, track: &'b Track) -> Self { 19 | Wrap { 20 | delegate, 21 | chain, 22 | track, 23 | } 24 | } 25 | } 26 | 27 | impl<'a, 'b, X> WrapVariant<'a, 'b, X> { 28 | pub(crate) fn new(delegate: X, chain: Chain<'a>, track: &'b Track) -> Self { 29 | WrapVariant { 30 | delegate, 31 | chain, 32 | track, 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_path_to_error" 3 | version = "0.1.20" 4 | authors = ["David Tolnay "] 5 | categories = ["encoding", "no-std"] 6 | description = "Path to the element that failed to deserialize" 7 | documentation = "https://docs.rs/serde_path_to_error" 8 | edition = "2021" 9 | keywords = ["serde", "serialization"] 10 | license = "MIT OR Apache-2.0" 11 | repository = "https://github.com/dtolnay/path-to-error" 12 | rust-version = "1.68" 13 | 14 | [dependencies] 15 | itoa = "1.0" 16 | serde_core = { version = "1.0.220", default-features = false, features = ["alloc"] } 17 | 18 | [target.'cfg(any())'.dependencies] 19 | serde = { version = "1.0.220", default-features = false } 20 | 21 | [dev-dependencies] 22 | serde = "1.0.220" 23 | serde_derive = "1.0.220" 24 | serde_json = "1.0.100" 25 | 26 | [package.metadata.docs.rs] 27 | targets = ["x86_64-unknown-linux-gnu"] 28 | rustdoc-args = [ 29 | "--generate-link-to-definition", 30 | "--generate-macro-expansion", 31 | "--extern-html-root-url=core=https://doc.rust-lang.org", 32 | "--extern-html-root-url=alloc=https://doc.rust-lang.org", 33 | "--extern-html-root-url=std=https://doc.rust-lang.org", 34 | ] 35 | -------------------------------------------------------------------------------- /tests/serialize.rs: -------------------------------------------------------------------------------- 1 | use serde::Serialize; 2 | use serde_derive::Serialize; 3 | use std::cell::RefCell; 4 | use std::collections::BTreeMap; 5 | use std::fmt::Debug; 6 | 7 | fn test(value: &T, expected: &str) 8 | where 9 | T: ?Sized + Serialize + Debug, 10 | { 11 | let mut out = Vec::new(); 12 | let ser = &mut serde_json::Serializer::new(&mut out); 13 | let result = serde_path_to_error::serialize(value, ser); 14 | let path = result.unwrap_err().path().to_string(); 15 | assert_eq!(path, expected); 16 | } 17 | 18 | #[test] 19 | fn test_refcell_already_borrowed() { 20 | #[derive(Serialize, Debug)] 21 | struct Outer<'a> { 22 | k: Inner<'a>, 23 | } 24 | 25 | #[derive(Serialize, Debug)] 26 | struct Inner<'a> { 27 | refcell: &'a RefCell, 28 | } 29 | 30 | let refcell = RefCell::new(String::new()); 31 | let outer = Outer { 32 | k: Inner { refcell: &refcell }, 33 | }; 34 | 35 | let _borrowed = refcell.borrow_mut(); 36 | test(&outer, "k.refcell"); 37 | } 38 | 39 | #[test] 40 | fn test_map_nonstring_key() { 41 | fn singleton_map(key: K, value: V) -> BTreeMap { 42 | let mut map = BTreeMap::new(); 43 | map.insert(key, value); 44 | map 45 | } 46 | 47 | let map = singleton_map(b"", 0); 48 | let map = singleton_map("k", map); 49 | let map = singleton_map(100, map); 50 | 51 | test(&map, "100.k"); 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serde path to error 2 | 3 | [github](https://github.com/dtolnay/path-to-error) 4 | [crates.io](https://crates.io/crates/serde_path_to_error) 5 | [docs.rs](https://docs.rs/serde_path_to_error) 6 | [build status](https://github.com/dtolnay/path-to-error/actions?query=branch%3Amaster) 7 | 8 | Find out the path at which a deserialization error occurred. This crate provides 9 | a wrapper that works with any existing Serde `Deserializer` and exposes the 10 | chain of field names leading to the error. 11 | 12 | ```toml 13 | [dependencies] 14 | serde = "1.0" 15 | serde_path_to_error = "0.1" 16 | ``` 17 | 18 | ```rust 19 | use serde::Deserialize; 20 | use std::collections::BTreeMap as Map; 21 | 22 | #[derive(Deserialize)] 23 | struct Package { 24 | name: String, 25 | dependencies: Map, 26 | } 27 | 28 | #[derive(Deserialize)] 29 | struct Dependency { 30 | version: String, 31 | } 32 | 33 | fn main() { 34 | let j = r#"{ 35 | "name": "demo", 36 | "dependencies": { 37 | "serde": { 38 | "version": 1 39 | } 40 | } 41 | }"#; 42 | 43 | // Some Deserializer. 44 | let jd = &mut serde_json::Deserializer::from_str(j); 45 | 46 | let result: Result = serde_path_to_error::deserialize(jd); 47 | match result { 48 | Ok(_) => panic!("expected a type error"), 49 | Err(err) => { 50 | let path = err.path().to_string(); 51 | assert_eq!(path, "dependencies.serde.version"); 52 | } 53 | } 54 | } 55 | ``` 56 | 57 |
58 | 59 | #### License 60 | 61 | 62 | Licensed under either of Apache License, Version 63 | 2.0 or MIT license at your option. 64 | 65 | 66 |
67 | 68 | 69 | Unless you explicitly state otherwise, any contribution intentionally submitted 70 | for inclusion in this crate by you, as defined in the Apache-2.0 license, shall 71 | be dual licensed as above, without any additional terms or conditions. 72 | 73 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | schedule: [cron: "40 1 * * *"] 8 | 9 | permissions: 10 | contents: read 11 | 12 | env: 13 | RUSTFLAGS: -Dwarnings 14 | 15 | jobs: 16 | pre_ci: 17 | uses: dtolnay/.github/.github/workflows/pre_ci.yml@master 18 | 19 | test: 20 | name: Rust ${{matrix.rust}} 21 | needs: pre_ci 22 | if: needs.pre_ci.outputs.continue 23 | runs-on: ubuntu-latest 24 | strategy: 25 | fail-fast: false 26 | matrix: 27 | rust: [nightly, beta, stable, 1.68.0] 28 | timeout-minutes: 45 29 | steps: 30 | - uses: actions/checkout@v6 31 | - uses: dtolnay/rust-toolchain@master 32 | with: 33 | toolchain: ${{matrix.rust}} 34 | - name: Enable type layout randomization 35 | run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV 36 | if: matrix.rust == 'nightly' 37 | - run: cargo test 38 | - uses: actions/upload-artifact@v6 39 | if: matrix.rust == 'nightly' && always() 40 | with: 41 | name: Cargo.lock 42 | path: Cargo.lock 43 | continue-on-error: true 44 | 45 | minimal: 46 | name: Minimal versions 47 | needs: pre_ci 48 | if: needs.pre_ci.outputs.continue 49 | runs-on: ubuntu-latest 50 | timeout-minutes: 45 51 | steps: 52 | - uses: actions/checkout@v6 53 | - uses: dtolnay/rust-toolchain@nightly 54 | - run: cargo generate-lockfile -Z minimal-versions 55 | - run: cargo check --locked 56 | 57 | doc: 58 | name: Documentation 59 | needs: pre_ci 60 | if: needs.pre_ci.outputs.continue 61 | runs-on: ubuntu-latest 62 | timeout-minutes: 45 63 | env: 64 | RUSTDOCFLAGS: -Dwarnings 65 | steps: 66 | - uses: actions/checkout@v6 67 | - uses: dtolnay/rust-toolchain@master 68 | with: 69 | # https://github.com/rust-lang/rust/issues/148617 70 | toolchain: nightly-2025-11-06 71 | - uses: dtolnay/install@cargo-docs-rs 72 | - run: cargo docs-rs 73 | 74 | clippy: 75 | name: Clippy 76 | runs-on: ubuntu-latest 77 | if: github.event_name != 'pull_request' 78 | timeout-minutes: 45 79 | steps: 80 | - uses: actions/checkout@v6 81 | - uses: dtolnay/rust-toolchain@clippy 82 | - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic 83 | 84 | miri: 85 | name: Miri 86 | needs: pre_ci 87 | if: needs.pre_ci.outputs.continue 88 | runs-on: ubuntu-latest 89 | timeout-minutes: 45 90 | steps: 91 | - uses: actions/checkout@v6 92 | - uses: dtolnay/rust-toolchain@miri 93 | - run: cargo miri setup 94 | - run: cargo miri test 95 | env: 96 | MIRIFLAGS: -Zmiri-strict-provenance 97 | 98 | outdated: 99 | name: Outdated 100 | runs-on: ubuntu-latest 101 | if: github.event_name != 'pull_request' 102 | timeout-minutes: 45 103 | steps: 104 | - uses: actions/checkout@v6 105 | - uses: dtolnay/rust-toolchain@stable 106 | - uses: dtolnay/install@cargo-outdated 107 | - run: cargo outdated --workspace --exit-code 1 108 | -------------------------------------------------------------------------------- /src/path.rs: -------------------------------------------------------------------------------- 1 | use super::Chain; 2 | use alloc::borrow::ToOwned as _; 3 | use alloc::string::String; 4 | use alloc::vec::Vec; 5 | use core::fmt::{self, Display}; 6 | use core::slice; 7 | 8 | /// Path to the error value in the input, like `dependencies.serde.typo1`. 9 | /// 10 | /// Use `path.to_string()` to get a string representation of the path with 11 | /// segments separated by periods, or use `path.iter()` to iterate over 12 | /// individual segments of the path. 13 | #[derive(Clone, Debug)] 14 | pub struct Path { 15 | segments: Vec, 16 | } 17 | 18 | /// Single segment of a path. 19 | #[derive(Clone, Debug)] 20 | pub enum Segment { 21 | Seq { index: usize }, 22 | Map { key: String }, 23 | Enum { variant: String }, 24 | Unknown, 25 | } 26 | 27 | impl Path { 28 | /// Returns an iterator with element type [`&Segment`][Segment]. 29 | pub fn iter(&self) -> Segments { 30 | Segments { 31 | iter: self.segments.iter(), 32 | } 33 | } 34 | } 35 | 36 | impl<'a> IntoIterator for &'a Path { 37 | type Item = &'a Segment; 38 | type IntoIter = Segments<'a>; 39 | 40 | fn into_iter(self) -> Self::IntoIter { 41 | self.iter() 42 | } 43 | } 44 | 45 | /// Iterator over segments of a path. 46 | pub struct Segments<'a> { 47 | iter: slice::Iter<'a, Segment>, 48 | } 49 | 50 | impl<'a> Iterator for Segments<'a> { 51 | type Item = &'a Segment; 52 | 53 | fn next(&mut self) -> Option { 54 | self.iter.next() 55 | } 56 | 57 | fn size_hint(&self) -> (usize, Option) { 58 | self.iter.size_hint() 59 | } 60 | } 61 | 62 | impl<'a> DoubleEndedIterator for Segments<'a> { 63 | fn next_back(&mut self) -> Option { 64 | self.iter.next_back() 65 | } 66 | } 67 | 68 | impl<'a> ExactSizeIterator for Segments<'a> { 69 | fn len(&self) -> usize { 70 | self.iter.len() 71 | } 72 | } 73 | 74 | impl Display for Path { 75 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 76 | if self.segments.is_empty() { 77 | return formatter.write_str("."); 78 | } 79 | 80 | let mut separator = ""; 81 | for segment in self { 82 | if !matches!(segment, Segment::Seq { .. }) { 83 | formatter.write_str(separator)?; 84 | } 85 | write!(formatter, "{}", segment)?; 86 | separator = "."; 87 | } 88 | 89 | Ok(()) 90 | } 91 | } 92 | 93 | impl Path { 94 | pub(crate) fn empty() -> Self { 95 | Path { 96 | segments: Vec::new(), 97 | } 98 | } 99 | 100 | pub(crate) fn from_chain(mut chain: &Chain) -> Self { 101 | let mut segments = Vec::new(); 102 | loop { 103 | match chain { 104 | Chain::Root => break, 105 | Chain::Seq { parent, index } => { 106 | segments.push(Segment::Seq { index: *index }); 107 | chain = parent; 108 | } 109 | Chain::Map { parent, key } => { 110 | segments.push(Segment::Map { key: key.clone() }); 111 | chain = parent; 112 | } 113 | Chain::Struct { parent, key } => { 114 | let key = *key; 115 | segments.push(Segment::Map { 116 | key: key.to_owned(), 117 | }); 118 | chain = parent; 119 | } 120 | Chain::Enum { parent, variant } => { 121 | segments.push(Segment::Enum { 122 | variant: variant.clone(), 123 | }); 124 | chain = parent; 125 | } 126 | Chain::Some { parent } 127 | | Chain::NewtypeStruct { parent } 128 | | Chain::NewtypeVariant { parent } => { 129 | chain = parent; 130 | } 131 | Chain::NonStringKey { parent } => { 132 | segments.push(Segment::Unknown); 133 | chain = parent; 134 | } 135 | } 136 | } 137 | segments.reverse(); 138 | Path { segments } 139 | } 140 | 141 | pub(crate) fn is_only_unknown(&self) -> bool { 142 | self.segments.iter().all(Segment::is_unknown) 143 | } 144 | } 145 | 146 | impl Display for Segment { 147 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 148 | match self { 149 | Segment::Seq { index } => write!(formatter, "[{}]", index), 150 | Segment::Map { key } | Segment::Enum { variant: key } => { 151 | write!(formatter, "{}", key) 152 | } 153 | Segment::Unknown => formatter.write_str("?"), 154 | } 155 | } 156 | } 157 | 158 | impl Segment { 159 | fn is_unknown(&self) -> bool { 160 | matches!(self, Segment::Unknown) 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /tests/deserialize.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::unreadable_literal, dead_code)] 2 | 3 | use serde::Deserialize; 4 | use serde_derive::Deserialize; 5 | use std::collections::BTreeMap as Map; 6 | use std::fmt::Debug; 7 | 8 | fn test<'de, T>(json: &'de str, expected: &str) 9 | where 10 | T: Deserialize<'de> + Debug, 11 | { 12 | let de = &mut serde_json::Deserializer::from_str(json); 13 | let result: Result = serde_path_to_error::deserialize(de); 14 | let path = result.unwrap_err().path().to_string(); 15 | assert_eq!(path, expected); 16 | } 17 | 18 | #[test] 19 | fn test_struct() { 20 | #[derive(Deserialize, Debug)] 21 | struct Package { 22 | name: String, 23 | dependencies: Map, 24 | } 25 | 26 | #[derive(Deserialize, Debug)] 27 | struct Dependency { 28 | version: String, 29 | } 30 | 31 | let j = r#"{ 32 | "name": "demo", 33 | "dependencies": { 34 | "serde": { 35 | "version": 1 36 | } 37 | } 38 | }"#; 39 | 40 | test::(j, "dependencies.serde.version"); 41 | } 42 | 43 | #[test] 44 | fn test_vec() { 45 | #[derive(Deserialize, Debug)] 46 | struct Package { 47 | dependencies: Vec, 48 | } 49 | 50 | #[derive(Deserialize, Debug)] 51 | struct Dependency { 52 | name: String, 53 | version: String, 54 | } 55 | 56 | let j = r#"{ 57 | "dependencies": [ 58 | { 59 | "name": "serde", 60 | "version": "1.0" 61 | }, 62 | { 63 | "name": "serde_json", 64 | "version": 1 65 | } 66 | } 67 | }"#; 68 | 69 | test::(j, "dependencies[1].version"); 70 | } 71 | 72 | #[test] 73 | fn test_option() { 74 | #[derive(Deserialize, Debug)] 75 | struct Package { 76 | dependency: Option, 77 | } 78 | 79 | #[derive(Deserialize, Debug)] 80 | struct Dependency { 81 | version: String, 82 | } 83 | 84 | let j = r#"{ 85 | "dependency": { 86 | "version": 1 87 | } 88 | }"#; 89 | 90 | test::(j, "dependency.version"); 91 | } 92 | 93 | #[test] 94 | fn test_struct_variant() { 95 | #[derive(Deserialize, Debug)] 96 | struct Package { 97 | dependency: Dependency, 98 | } 99 | 100 | #[derive(Deserialize, Debug)] 101 | enum Dependency { 102 | Struct { version: String }, 103 | } 104 | 105 | let j = r#"{ 106 | "dependency": { 107 | "Struct": { 108 | "version": 1 109 | } 110 | } 111 | }"#; 112 | 113 | test::(j, "dependency.Struct.version"); 114 | } 115 | 116 | #[test] 117 | fn test_tuple_variant() { 118 | #[derive(Deserialize, Debug)] 119 | struct Package { 120 | dependency: Dependency, 121 | } 122 | 123 | #[derive(Deserialize, Debug)] 124 | enum Dependency { 125 | Tuple(String, String), 126 | } 127 | 128 | let j = r#"{ 129 | "dependency": { 130 | "Tuple": ["serde", 1] 131 | } 132 | }"#; 133 | 134 | test::(j, "dependency.Tuple[1]"); 135 | } 136 | 137 | #[test] 138 | fn test_unknown_field() { 139 | #[derive(Deserialize, Debug)] 140 | struct Package { 141 | dependency: Dependency, 142 | } 143 | 144 | #[derive(Deserialize, Debug)] 145 | #[serde(deny_unknown_fields)] 146 | struct Dependency { 147 | version: String, 148 | } 149 | 150 | let j = r#"{ 151 | "dependency": { 152 | "version": "1.0", 153 | "name": "serde" 154 | } 155 | }"#; 156 | 157 | test::(j, "dependency.name"); 158 | } 159 | 160 | #[test] 161 | fn test_invalid_length() { 162 | #[derive(Deserialize, Debug)] 163 | struct Package { 164 | dependency: Dependency, 165 | } 166 | 167 | #[derive(Deserialize, Debug)] 168 | struct Dependency(String, String); 169 | 170 | let j = r#"{ 171 | "dependency": ["serde"] 172 | }"#; 173 | 174 | test::(j, "dependency"); 175 | } 176 | 177 | #[test] 178 | fn test_syntax_error() { 179 | #[derive(Deserialize, Debug)] 180 | struct Package { 181 | dependency: Dependency, 182 | } 183 | 184 | #[derive(Deserialize, Debug)] 185 | struct Dependency { 186 | version: String, 187 | } 188 | 189 | let j = r#"{ 190 | "dependency": { 191 | "error": * 192 | }"#; 193 | 194 | test::(j, "dependency.error"); 195 | } 196 | 197 | #[test] 198 | fn test_u128() { 199 | #[derive(Deserialize, Debug)] 200 | struct Container { 201 | n: u128, 202 | } 203 | 204 | let j = r#"{ 205 | "n": 130033514578017493995102500318550798591 206 | }"#; 207 | 208 | let de = &mut serde_json::Deserializer::from_str(j); 209 | let container: Container = serde_path_to_error::deserialize(de).expect("failed to deserialize"); 210 | 211 | assert_eq!(container.n, 130033514578017493995102500318550798591u128); 212 | } 213 | 214 | #[test] 215 | fn test_map_nonstring_key() { 216 | #[derive(Deserialize, Debug)] 217 | struct Dependency { 218 | version: String, 219 | } 220 | 221 | let j = r#"{ 222 | "100": { 223 | "version": false 224 | } 225 | }"#; 226 | 227 | test::>(j, "100.version"); 228 | } 229 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! [![github]](https://github.com/dtolnay/path-to-error) [![crates-io]](https://crates.io/crates/serde_path_to_error) [![docs-rs]](https://docs.rs/serde_path_to_error) 2 | //! 3 | //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github 4 | //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust 5 | //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs 6 | //! 7 | //!
8 | //! 9 | //! Find out the path at which a deserialization error occurred. This crate 10 | //! provides a wrapper that works with any existing Serde `Deserializer` and 11 | //! exposes the chain of field names leading to the error. 12 | //! 13 | //! # Example 14 | //! 15 | //! ``` 16 | //! # use serde_derive::Deserialize; 17 | //! # 18 | //! use serde::Deserialize; 19 | //! use std::collections::BTreeMap as Map; 20 | //! 21 | //! #[derive(Deserialize)] 22 | //! struct Package { 23 | //! name: String, 24 | //! dependencies: Map, 25 | //! } 26 | //! 27 | //! #[derive(Deserialize)] 28 | //! struct Dependency { 29 | //! version: String, 30 | //! } 31 | //! 32 | //! fn main() { 33 | //! let j = r#"{ 34 | //! "name": "demo", 35 | //! "dependencies": { 36 | //! "serde": { 37 | //! "version": 1 38 | //! } 39 | //! } 40 | //! }"#; 41 | //! 42 | //! // Some Deserializer. 43 | //! let jd = &mut serde_json::Deserializer::from_str(j); 44 | //! 45 | //! let result: Result = serde_path_to_error::deserialize(jd); 46 | //! match result { 47 | //! Ok(_) => panic!("expected a type error"), 48 | //! Err(err) => { 49 | //! let path = err.path().to_string(); 50 | //! assert_eq!(path, "dependencies.serde.version"); 51 | //! } 52 | //! } 53 | //! } 54 | //! ``` 55 | 56 | #![doc(html_root_url = "https://docs.rs/serde_path_to_error/0.1.20")] 57 | #![no_std] 58 | #![allow( 59 | clippy::doc_link_with_quotes, // https://github.com/rust-lang/rust-clippy/issues/8961 60 | clippy::elidable_lifetime_names, 61 | clippy::iter_not_returning_iterator, // https://github.com/rust-lang/rust-clippy/issues/8285 62 | clippy::missing_errors_doc, 63 | clippy::module_name_repetitions, 64 | clippy::must_use_candidate, 65 | clippy::needless_lifetimes, 66 | clippy::new_without_default, 67 | clippy::uninlined_format_args 68 | )] 69 | #![allow(unknown_lints, mismatched_lifetime_syntaxes)] 70 | 71 | extern crate alloc; 72 | extern crate serde_core as serde; 73 | 74 | mod de; 75 | mod path; 76 | mod ser; 77 | mod wrap; 78 | 79 | use alloc::string::String; 80 | use core::cell::Cell; 81 | use core::fmt::{self, Display}; 82 | use serde::ser::StdError; 83 | 84 | pub use crate::de::{deserialize, Deserializer}; 85 | pub use crate::path::{Path, Segment, Segments}; 86 | pub use crate::ser::{serialize, Serializer}; 87 | 88 | /// Original deserializer error together with the path at which it occurred. 89 | #[derive(Clone, Debug)] 90 | pub struct Error { 91 | path: Path, 92 | original: E, 93 | } 94 | 95 | impl Error { 96 | pub fn new(path: Path, inner: E) -> Self { 97 | Error { 98 | path, 99 | original: inner, 100 | } 101 | } 102 | 103 | /// Element path at which this deserialization error occurred. 104 | pub fn path(&self) -> &Path { 105 | &self.path 106 | } 107 | 108 | /// The Deserializer's underlying error that occurred. 109 | pub fn into_inner(self) -> E { 110 | self.original 111 | } 112 | 113 | /// Reference to the Deserializer's underlying error that occurred. 114 | pub fn inner(&self) -> &E { 115 | &self.original 116 | } 117 | } 118 | 119 | impl Display for Error { 120 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 121 | if !self.path.is_only_unknown() { 122 | write!(f, "{}: ", self.path)?; 123 | } 124 | write!(f, "{}", self.original) 125 | } 126 | } 127 | 128 | impl StdError for Error { 129 | fn source(&self) -> Option<&(dyn StdError + 'static)> { 130 | self.original.source() 131 | } 132 | } 133 | 134 | /// State for bookkeeping across nested deserializer calls. 135 | /// 136 | /// You don't need this if you are using `serde_path_to_error::deserializer`. If 137 | /// you are managing your own `Deserializer`, see the usage example on 138 | /// [`Deserializer`]. 139 | pub struct Track { 140 | path: Cell>, 141 | } 142 | 143 | impl Track { 144 | /// Empty state with no error having happened yet. 145 | pub const fn new() -> Self { 146 | Track { 147 | path: Cell::new(None), 148 | } 149 | } 150 | 151 | /// Gets path at which the error occurred. Only meaningful after we know 152 | /// that an error has occurred. Returns an empty path otherwise. 153 | pub fn path(self) -> Path { 154 | self.path.into_inner().unwrap_or_else(Path::empty) 155 | } 156 | 157 | #[inline] 158 | fn trigger(&self, chain: &Chain, err: E) -> E { 159 | self.trigger_impl(chain); 160 | err 161 | } 162 | 163 | fn trigger_impl(&self, chain: &Chain) { 164 | self.path.set(Some(match self.path.take() { 165 | Some(already_set) => already_set, 166 | None => Path::from_chain(chain), 167 | })); 168 | } 169 | } 170 | 171 | #[derive(Clone)] 172 | enum Chain<'a> { 173 | Root, 174 | Seq { 175 | parent: &'a Chain<'a>, 176 | index: usize, 177 | }, 178 | Map { 179 | parent: &'a Chain<'a>, 180 | key: String, 181 | }, 182 | Struct { 183 | parent: &'a Chain<'a>, 184 | key: &'static str, 185 | }, 186 | Enum { 187 | parent: &'a Chain<'a>, 188 | variant: String, 189 | }, 190 | Some { 191 | parent: &'a Chain<'a>, 192 | }, 193 | NewtypeStruct { 194 | parent: &'a Chain<'a>, 195 | }, 196 | NewtypeVariant { 197 | parent: &'a Chain<'a>, 198 | }, 199 | NonStringKey { 200 | parent: &'a Chain<'a>, 201 | }, 202 | } 203 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/ser.rs: -------------------------------------------------------------------------------- 1 | use crate::wrap::Wrap; 2 | use crate::{Chain, Error, Track}; 3 | use alloc::borrow::ToOwned as _; 4 | use alloc::string::{String, ToString as _}; 5 | use core::cell::Cell; 6 | use core::fmt::Display; 7 | use serde::ser::{self, Serialize}; 8 | 9 | /// Entry point for tracking path to Serialize error. 10 | /// 11 | /// # Example 12 | /// 13 | /// ``` 14 | /// # use serde_derive::Serialize; 15 | /// # 16 | /// use serde::Serialize; 17 | /// use std::cell::RefCell; 18 | /// 19 | /// #[derive(Serialize)] 20 | /// struct Outer<'a> { 21 | /// k: Inner<'a>, 22 | /// } 23 | /// 24 | /// #[derive(Serialize)] 25 | /// struct Inner<'a> { 26 | /// refcell: &'a RefCell, 27 | /// } 28 | /// 29 | /// let refcell = RefCell::new(String::new()); 30 | /// let value = Outer { 31 | /// k: Inner { refcell: &refcell }, 32 | /// }; 33 | /// 34 | /// // A RefCell cannot be serialized while it is still mutably borrowed. 35 | /// let _borrowed = refcell.borrow_mut(); 36 | /// 37 | /// // Some Serializer. 38 | /// let mut out = Vec::new(); 39 | /// let jser = &mut serde_json::Serializer::new(&mut out); 40 | /// 41 | /// let result = serde_path_to_error::serialize(&value, jser); 42 | /// match result { 43 | /// Ok(_) => panic!("expected failure to serialize RefCell"), 44 | /// Err(err) => { 45 | /// let path = err.path().to_string(); 46 | /// assert_eq!(path, "k.refcell"); 47 | /// } 48 | /// } 49 | /// ``` 50 | pub fn serialize(value: &T, serializer: S) -> Result> 51 | where 52 | T: ?Sized + Serialize, 53 | S: ser::Serializer, 54 | { 55 | let mut track = Track::new(); 56 | match T::serialize(value, Serializer::new(serializer, &mut track)) { 57 | Ok(ok) => Ok(ok), 58 | Err(err) => Err(Error { 59 | path: track.path(), 60 | original: err, 61 | }), 62 | } 63 | } 64 | 65 | /// Serializer adapter that records path to serialization errors. 66 | /// 67 | /// # Example 68 | /// 69 | /// ``` 70 | /// # use serde_derive::Serialize; 71 | /// # 72 | /// use serde::Serialize; 73 | /// use std::collections::BTreeMap; 74 | /// 75 | /// // Maps with a non-string key are not valid in JSON. 76 | /// let mut inner_map = BTreeMap::new(); 77 | /// inner_map.insert(vec!['w', 'a', 't'], 0); 78 | /// 79 | /// let mut outer_map = BTreeMap::new(); 80 | /// outer_map.insert("k", inner_map); 81 | /// 82 | /// // Some Serializer. 83 | /// let mut out = Vec::new(); 84 | /// let jser = &mut serde_json::Serializer::new(&mut out); 85 | /// 86 | /// let mut track = serde_path_to_error::Track::new(); 87 | /// let ps = serde_path_to_error::Serializer::new(jser, &mut track); 88 | /// 89 | /// match outer_map.serialize(ps) { 90 | /// Ok(_) => panic!("expected failure to serialize non-string key"), 91 | /// Err(_) => { 92 | /// let path = track.path().to_string(); 93 | /// assert_eq!(path, "k"); 94 | /// } 95 | /// } 96 | /// ``` 97 | pub struct Serializer<'a, 'b, S> { 98 | ser: S, 99 | chain: &'a Chain<'a>, 100 | track: &'b Track, 101 | } 102 | 103 | impl<'a, 'b, S> Serializer<'a, 'b, S> { 104 | #[allow(clippy::needless_pass_by_ref_mut)] 105 | pub fn new(ser: S, track: &'b mut Track) -> Self { 106 | Serializer { 107 | ser, 108 | chain: &Chain::Root, 109 | track, 110 | } 111 | } 112 | } 113 | 114 | impl<'a, 'b, S> ser::Serializer for Serializer<'a, 'b, S> 115 | where 116 | S: ser::Serializer, 117 | { 118 | type Ok = S::Ok; 119 | type Error = S::Error; 120 | type SerializeSeq = WrapSeq<'a, 'b, S::SerializeSeq>; 121 | type SerializeTuple = WrapSeq<'a, 'b, S::SerializeTuple>; 122 | type SerializeTupleStruct = WrapSeq<'a, 'b, S::SerializeTupleStruct>; 123 | type SerializeTupleVariant = WrapSeq<'a, 'b, S::SerializeTupleVariant>; 124 | type SerializeMap = WrapMap<'a, 'b, S::SerializeMap>; 125 | type SerializeStruct = Wrap<'a, 'b, S::SerializeStruct>; 126 | type SerializeStructVariant = Wrap<'a, 'b, S::SerializeStructVariant>; 127 | 128 | fn serialize_bool(self, v: bool) -> Result { 129 | let chain = self.chain; 130 | let track = self.track; 131 | self.ser 132 | .serialize_bool(v) 133 | .map_err(|err| track.trigger(chain, err)) 134 | } 135 | 136 | fn serialize_i8(self, v: i8) -> Result { 137 | let chain = self.chain; 138 | let track = self.track; 139 | self.ser 140 | .serialize_i8(v) 141 | .map_err(|err| track.trigger(chain, err)) 142 | } 143 | 144 | fn serialize_i16(self, v: i16) -> Result { 145 | let chain = self.chain; 146 | let track = self.track; 147 | self.ser 148 | .serialize_i16(v) 149 | .map_err(|err| track.trigger(chain, err)) 150 | } 151 | 152 | fn serialize_i32(self, v: i32) -> Result { 153 | let chain = self.chain; 154 | let track = self.track; 155 | self.ser 156 | .serialize_i32(v) 157 | .map_err(|err| track.trigger(chain, err)) 158 | } 159 | 160 | fn serialize_i64(self, v: i64) -> Result { 161 | let chain = self.chain; 162 | let track = self.track; 163 | self.ser 164 | .serialize_i64(v) 165 | .map_err(|err| track.trigger(chain, err)) 166 | } 167 | 168 | fn serialize_i128(self, v: i128) -> Result { 169 | let chain = self.chain; 170 | let track = self.track; 171 | self.ser 172 | .serialize_i128(v) 173 | .map_err(|err| track.trigger(chain, err)) 174 | } 175 | 176 | fn serialize_u8(self, v: u8) -> Result { 177 | let chain = self.chain; 178 | let track = self.track; 179 | self.ser 180 | .serialize_u8(v) 181 | .map_err(|err| track.trigger(chain, err)) 182 | } 183 | 184 | fn serialize_u16(self, v: u16) -> Result { 185 | let chain = self.chain; 186 | let track = self.track; 187 | self.ser 188 | .serialize_u16(v) 189 | .map_err(|err| track.trigger(chain, err)) 190 | } 191 | 192 | fn serialize_u32(self, v: u32) -> Result { 193 | let chain = self.chain; 194 | let track = self.track; 195 | self.ser 196 | .serialize_u32(v) 197 | .map_err(|err| track.trigger(chain, err)) 198 | } 199 | 200 | fn serialize_u64(self, v: u64) -> Result { 201 | let chain = self.chain; 202 | let track = self.track; 203 | self.ser 204 | .serialize_u64(v) 205 | .map_err(|err| track.trigger(chain, err)) 206 | } 207 | 208 | fn serialize_u128(self, v: u128) -> Result { 209 | let chain = self.chain; 210 | let track = self.track; 211 | self.ser 212 | .serialize_u128(v) 213 | .map_err(|err| track.trigger(chain, err)) 214 | } 215 | 216 | fn serialize_f32(self, v: f32) -> Result { 217 | let chain = self.chain; 218 | let track = self.track; 219 | self.ser 220 | .serialize_f32(v) 221 | .map_err(|err| track.trigger(chain, err)) 222 | } 223 | 224 | fn serialize_f64(self, v: f64) -> Result { 225 | let chain = self.chain; 226 | let track = self.track; 227 | self.ser 228 | .serialize_f64(v) 229 | .map_err(|err| track.trigger(chain, err)) 230 | } 231 | 232 | fn serialize_char(self, v: char) -> Result { 233 | let chain = self.chain; 234 | let track = self.track; 235 | self.ser 236 | .serialize_char(v) 237 | .map_err(|err| track.trigger(chain, err)) 238 | } 239 | 240 | fn serialize_str(self, v: &str) -> Result { 241 | let chain = self.chain; 242 | let track = self.track; 243 | self.ser 244 | .serialize_str(v) 245 | .map_err(|err| track.trigger(chain, err)) 246 | } 247 | 248 | fn serialize_bytes(self, v: &[u8]) -> Result { 249 | let chain = self.chain; 250 | let track = self.track; 251 | self.ser 252 | .serialize_bytes(v) 253 | .map_err(|err| track.trigger(chain, err)) 254 | } 255 | 256 | fn serialize_none(self) -> Result { 257 | let chain = self.chain; 258 | let track = self.track; 259 | self.ser 260 | .serialize_none() 261 | .map_err(|err| track.trigger(chain, err)) 262 | } 263 | 264 | fn serialize_some(self, value: &T) -> Result 265 | where 266 | T: ?Sized + Serialize, 267 | { 268 | let chain = self.chain; 269 | let track = self.track; 270 | self.ser 271 | .serialize_some(value) 272 | .map_err(|err| track.trigger(chain, err)) 273 | } 274 | 275 | fn serialize_unit(self) -> Result { 276 | let chain = self.chain; 277 | let track = self.track; 278 | self.ser 279 | .serialize_unit() 280 | .map_err(|err| track.trigger(chain, err)) 281 | } 282 | 283 | fn serialize_unit_struct(self, name: &'static str) -> Result { 284 | let chain = self.chain; 285 | let track = self.track; 286 | self.ser 287 | .serialize_unit_struct(name) 288 | .map_err(|err| track.trigger(chain, err)) 289 | } 290 | 291 | fn serialize_unit_variant( 292 | self, 293 | name: &'static str, 294 | variant_index: u32, 295 | variant: &'static str, 296 | ) -> Result { 297 | let chain = self.chain; 298 | let track = self.track; 299 | self.ser 300 | .serialize_unit_variant(name, variant_index, variant) 301 | .map_err(|err| track.trigger(chain, err)) 302 | } 303 | 304 | fn serialize_newtype_struct( 305 | self, 306 | name: &'static str, 307 | value: &T, 308 | ) -> Result 309 | where 310 | T: ?Sized + Serialize, 311 | { 312 | let chain = self.chain; 313 | let track = self.track; 314 | self.ser 315 | .serialize_newtype_struct(name, value) 316 | .map_err(|err| track.trigger(chain, err)) 317 | } 318 | 319 | fn serialize_newtype_variant( 320 | self, 321 | name: &'static str, 322 | variant_index: u32, 323 | variant: &'static str, 324 | value: &T, 325 | ) -> Result 326 | where 327 | T: ?Sized + Serialize, 328 | { 329 | let chain = self.chain; 330 | let track = self.track; 331 | self.ser 332 | .serialize_newtype_variant(name, variant_index, variant, value) 333 | .map_err(|err| track.trigger(chain, err)) 334 | } 335 | 336 | fn serialize_seq(self, len: Option) -> Result { 337 | let chain = self.chain; 338 | let track = self.track; 339 | match self.ser.serialize_seq(len) { 340 | Ok(delegate) => Ok(WrapSeq::new(delegate, chain, track)), 341 | Err(err) => Err(track.trigger(chain, err)), 342 | } 343 | } 344 | 345 | fn serialize_tuple(self, len: usize) -> Result { 346 | let chain = self.chain; 347 | let track = self.track; 348 | match self.ser.serialize_tuple(len) { 349 | Ok(delegate) => Ok(WrapSeq::new(delegate, chain, track)), 350 | Err(err) => Err(track.trigger(chain, err)), 351 | } 352 | } 353 | 354 | fn serialize_tuple_struct( 355 | self, 356 | name: &'static str, 357 | len: usize, 358 | ) -> Result { 359 | let chain = self.chain; 360 | let track = self.track; 361 | match self.ser.serialize_tuple_struct(name, len) { 362 | Ok(delegate) => Ok(WrapSeq::new(delegate, chain, track)), 363 | Err(err) => Err(track.trigger(chain, err)), 364 | } 365 | } 366 | 367 | fn serialize_tuple_variant( 368 | self, 369 | name: &'static str, 370 | variant_index: u32, 371 | variant: &'static str, 372 | len: usize, 373 | ) -> Result { 374 | let chain = self.chain; 375 | let track = self.track; 376 | match self 377 | .ser 378 | .serialize_tuple_variant(name, variant_index, variant, len) 379 | { 380 | Ok(delegate) => Ok(WrapSeq::new(delegate, chain, track)), 381 | Err(err) => Err(track.trigger(chain, err)), 382 | } 383 | } 384 | 385 | fn serialize_map(self, len: Option) -> Result { 386 | let chain = self.chain; 387 | let track = self.track; 388 | match self.ser.serialize_map(len) { 389 | Ok(delegate) => Ok(WrapMap::new(delegate, chain, track)), 390 | Err(err) => Err(track.trigger(chain, err)), 391 | } 392 | } 393 | 394 | fn serialize_struct( 395 | self, 396 | name: &'static str, 397 | len: usize, 398 | ) -> Result { 399 | let chain = self.chain; 400 | let track = self.track; 401 | match self.ser.serialize_struct(name, len) { 402 | Ok(delegate) => Ok(Wrap::new(delegate, chain, track)), 403 | Err(err) => Err(track.trigger(chain, err)), 404 | } 405 | } 406 | 407 | fn serialize_struct_variant( 408 | self, 409 | name: &'static str, 410 | variant_index: u32, 411 | variant: &'static str, 412 | len: usize, 413 | ) -> Result { 414 | let chain = self.chain; 415 | let track = self.track; 416 | match self 417 | .ser 418 | .serialize_struct_variant(name, variant_index, variant, len) 419 | { 420 | Ok(delegate) => Ok(Wrap::new(delegate, chain, track)), 421 | Err(err) => Err(track.trigger(chain, err)), 422 | } 423 | } 424 | 425 | fn collect_str(self, value: &T) -> Result 426 | where 427 | T: ?Sized + Display, 428 | { 429 | let chain = self.chain; 430 | let track = self.track; 431 | self.ser 432 | .collect_str(value) 433 | .map_err(|err| track.trigger(chain, err)) 434 | } 435 | 436 | fn is_human_readable(&self) -> bool { 437 | self.ser.is_human_readable() 438 | } 439 | } 440 | 441 | struct TrackedValue<'a, 'b, X> { 442 | value: X, 443 | chain: &'a Chain<'a>, 444 | track: &'b Track, 445 | } 446 | 447 | impl<'a, 'b, X> TrackedValue<'a, 'b, X> { 448 | fn new(value: X, chain: &'a Chain<'a>, track: &'b Track) -> Self { 449 | TrackedValue { 450 | value, 451 | chain, 452 | track, 453 | } 454 | } 455 | } 456 | 457 | impl<'a, 'b, X> Serialize for TrackedValue<'a, 'b, X> 458 | where 459 | X: Serialize, 460 | { 461 | fn serialize(&self, serializer: S) -> Result 462 | where 463 | S: ser::Serializer, 464 | { 465 | let chain = self.chain; 466 | let track = self.track; 467 | self.value 468 | .serialize(Serializer { 469 | ser: serializer, 470 | chain, 471 | track, 472 | }) 473 | .map_err(|err| track.trigger(chain, err)) 474 | } 475 | } 476 | 477 | pub struct WrapSeq<'a, 'b, S> { 478 | delegate: S, 479 | chain: &'a Chain<'a>, 480 | index: usize, 481 | track: &'b Track, 482 | } 483 | 484 | impl<'a, 'b, S> WrapSeq<'a, 'b, S> { 485 | fn new(delegate: S, chain: &'a Chain<'a>, track: &'b Track) -> Self { 486 | WrapSeq { 487 | delegate, 488 | chain, 489 | index: 0, 490 | track, 491 | } 492 | } 493 | } 494 | 495 | impl<'a, 'b, S> ser::SerializeSeq for WrapSeq<'a, 'b, S> 496 | where 497 | S: ser::SerializeSeq, 498 | { 499 | type Ok = S::Ok; 500 | type Error = S::Error; 501 | 502 | fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> 503 | where 504 | T: ?Sized + Serialize, 505 | { 506 | let parent = self.chain; 507 | let chain = Chain::Seq { 508 | parent, 509 | index: self.index, 510 | }; 511 | let track = self.track; 512 | self.index += 1; 513 | self.delegate 514 | .serialize_element(&TrackedValue::new(value, &chain, track)) 515 | .map_err(|err| track.trigger(parent, err)) 516 | } 517 | 518 | fn end(self) -> Result { 519 | let chain = self.chain; 520 | let track = self.track; 521 | self.delegate.end().map_err(|err| track.trigger(chain, err)) 522 | } 523 | } 524 | 525 | impl<'a, 'b, S> ser::SerializeTuple for WrapSeq<'a, 'b, S> 526 | where 527 | S: ser::SerializeTuple, 528 | { 529 | type Ok = S::Ok; 530 | type Error = S::Error; 531 | 532 | fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> 533 | where 534 | T: ?Sized + Serialize, 535 | { 536 | let parent = self.chain; 537 | let chain = Chain::Seq { 538 | parent, 539 | index: self.index, 540 | }; 541 | let track = self.track; 542 | self.index += 1; 543 | self.delegate 544 | .serialize_element(&TrackedValue::new(value, &chain, track)) 545 | .map_err(|err| track.trigger(parent, err)) 546 | } 547 | 548 | fn end(self) -> Result { 549 | let chain = self.chain; 550 | let track = self.track; 551 | self.delegate.end().map_err(|err| track.trigger(chain, err)) 552 | } 553 | } 554 | 555 | impl<'a, 'b, S> ser::SerializeTupleStruct for WrapSeq<'a, 'b, S> 556 | where 557 | S: ser::SerializeTupleStruct, 558 | { 559 | type Ok = S::Ok; 560 | type Error = S::Error; 561 | 562 | fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> 563 | where 564 | T: ?Sized + Serialize, 565 | { 566 | let parent = self.chain; 567 | let chain = Chain::Seq { 568 | parent, 569 | index: self.index, 570 | }; 571 | let track = self.track; 572 | self.index += 1; 573 | self.delegate 574 | .serialize_field(&TrackedValue::new(value, &chain, track)) 575 | .map_err(|err| track.trigger(parent, err)) 576 | } 577 | 578 | fn end(self) -> Result { 579 | let chain = self.chain; 580 | let track = self.track; 581 | self.delegate.end().map_err(|err| track.trigger(chain, err)) 582 | } 583 | } 584 | 585 | impl<'a, 'b, S> ser::SerializeTupleVariant for WrapSeq<'a, 'b, S> 586 | where 587 | S: ser::SerializeTupleVariant, 588 | { 589 | type Ok = S::Ok; 590 | type Error = S::Error; 591 | 592 | fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> 593 | where 594 | T: ?Sized + Serialize, 595 | { 596 | let parent = self.chain; 597 | let chain = Chain::Seq { 598 | parent, 599 | index: self.index, 600 | }; 601 | let track = self.track; 602 | self.index += 1; 603 | self.delegate 604 | .serialize_field(&TrackedValue::new(value, &chain, track)) 605 | .map_err(|err| track.trigger(parent, err)) 606 | } 607 | 608 | fn end(self) -> Result { 609 | let chain = self.chain; 610 | let track = self.track; 611 | self.delegate.end().map_err(|err| track.trigger(chain, err)) 612 | } 613 | } 614 | 615 | pub struct WrapMap<'a, 'b, S> { 616 | delegate: S, 617 | chain: &'a Chain<'a>, 618 | key: Cell>, 619 | track: &'b Track, 620 | } 621 | 622 | impl<'a, 'b, S> WrapMap<'a, 'b, S> { 623 | fn new(delegate: S, chain: &'a Chain<'a>, track: &'b Track) -> Self { 624 | WrapMap { 625 | delegate, 626 | chain, 627 | key: Cell::new(None), 628 | track, 629 | } 630 | } 631 | } 632 | 633 | impl<'a, 'b, S> ser::SerializeMap for WrapMap<'a, 'b, S> 634 | where 635 | S: ser::SerializeMap, 636 | { 637 | type Ok = S::Ok; 638 | type Error = S::Error; 639 | 640 | fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> 641 | where 642 | T: ?Sized + Serialize, 643 | { 644 | let chain = self.chain; 645 | let track = self.track; 646 | self.key.set(None); 647 | self.delegate 648 | .serialize_key(&CaptureKey::new(&self.key, key)) 649 | .map_err(|err| track.trigger(chain, err)) 650 | } 651 | 652 | fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> 653 | where 654 | T: ?Sized + Serialize, 655 | { 656 | let parent = self.chain; 657 | let chain = match self.key.take() { 658 | Some(key) => Chain::Map { parent, key }, 659 | None => Chain::NonStringKey { parent }, 660 | }; 661 | let track = self.track; 662 | self.delegate 663 | .serialize_value(&TrackedValue::new(value, &chain, track)) 664 | .map_err(|err| track.trigger(parent, err)) 665 | } 666 | 667 | fn end(self) -> Result { 668 | let chain = self.chain; 669 | let track = self.track; 670 | self.delegate.end().map_err(|err| track.trigger(chain, err)) 671 | } 672 | } 673 | 674 | impl<'a, 'b, S> ser::SerializeStruct for Wrap<'a, 'b, S> 675 | where 676 | S: ser::SerializeStruct, 677 | { 678 | type Ok = S::Ok; 679 | type Error = S::Error; 680 | 681 | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> 682 | where 683 | T: ?Sized + Serialize, 684 | { 685 | let parent = self.chain; 686 | let chain = Chain::Struct { parent, key }; 687 | let track = self.track; 688 | self.delegate 689 | .serialize_field(key, &TrackedValue::new(value, &chain, track)) 690 | .map_err(|err| track.trigger(parent, err)) 691 | } 692 | 693 | fn end(self) -> Result { 694 | let chain = self.chain; 695 | let track = self.track; 696 | self.delegate.end().map_err(|err| track.trigger(chain, err)) 697 | } 698 | 699 | fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { 700 | let chain = self.chain; 701 | let track = self.track; 702 | self.delegate 703 | .skip_field(key) 704 | .map_err(|err| track.trigger(chain, err)) 705 | } 706 | } 707 | 708 | impl<'a, 'b, S> ser::SerializeStructVariant for Wrap<'a, 'b, S> 709 | where 710 | S: ser::SerializeStructVariant, 711 | { 712 | type Ok = S::Ok; 713 | type Error = S::Error; 714 | 715 | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> 716 | where 717 | T: ?Sized + Serialize, 718 | { 719 | let parent = self.chain; 720 | let chain = Chain::Struct { parent, key }; 721 | let track = self.track; 722 | self.delegate 723 | .serialize_field(key, &TrackedValue::new(value, &chain, track)) 724 | .map_err(|err| track.trigger(parent, err)) 725 | } 726 | 727 | fn end(self) -> Result { 728 | let chain = self.chain; 729 | let track = self.track; 730 | self.delegate.end().map_err(|err| track.trigger(chain, err)) 731 | } 732 | 733 | fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { 734 | let chain = self.chain; 735 | let track = self.track; 736 | self.delegate 737 | .skip_field(key) 738 | .map_err(|err| track.trigger(chain, err)) 739 | } 740 | } 741 | 742 | struct CaptureKey<'a, T> { 743 | out: &'a Cell>, 744 | delegate: T, 745 | } 746 | 747 | impl<'a, T> CaptureKey<'a, T> { 748 | fn new(out: &'a Cell>, delegate: T) -> Self { 749 | CaptureKey { out, delegate } 750 | } 751 | } 752 | 753 | impl<'a, T> Serialize for CaptureKey<'a, T> 754 | where 755 | T: Serialize, 756 | { 757 | fn serialize(&self, serializer: S) -> Result 758 | where 759 | S: ser::Serializer, 760 | { 761 | self.delegate 762 | .serialize(CaptureKey::new(self.out, serializer)) 763 | } 764 | } 765 | 766 | impl<'a, S> ser::Serializer for CaptureKey<'a, S> 767 | where 768 | S: ser::Serializer, 769 | { 770 | type Ok = S::Ok; 771 | type Error = S::Error; 772 | type SerializeSeq = S::SerializeSeq; 773 | type SerializeTuple = S::SerializeTuple; 774 | type SerializeTupleStruct = S::SerializeTupleStruct; 775 | type SerializeTupleVariant = S::SerializeTupleVariant; 776 | type SerializeMap = S::SerializeMap; 777 | type SerializeStruct = S::SerializeStruct; 778 | type SerializeStructVariant = S::SerializeStructVariant; 779 | 780 | fn serialize_bool(self, v: bool) -> Result { 781 | let string = if v { "true" } else { "false" }; 782 | self.out.set(Some(string.to_owned())); 783 | self.delegate.serialize_bool(v) 784 | } 785 | 786 | fn serialize_i8(self, v: i8) -> Result { 787 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 788 | self.delegate.serialize_i8(v) 789 | } 790 | 791 | fn serialize_i16(self, v: i16) -> Result { 792 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 793 | self.delegate.serialize_i16(v) 794 | } 795 | 796 | fn serialize_i32(self, v: i32) -> Result { 797 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 798 | self.delegate.serialize_i32(v) 799 | } 800 | 801 | fn serialize_i64(self, v: i64) -> Result { 802 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 803 | self.delegate.serialize_i64(v) 804 | } 805 | 806 | fn serialize_i128(self, v: i128) -> Result { 807 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 808 | self.delegate.serialize_i128(v) 809 | } 810 | 811 | fn serialize_u8(self, v: u8) -> Result { 812 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 813 | self.delegate.serialize_u8(v) 814 | } 815 | 816 | fn serialize_u16(self, v: u16) -> Result { 817 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 818 | self.delegate.serialize_u16(v) 819 | } 820 | 821 | fn serialize_u32(self, v: u32) -> Result { 822 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 823 | self.delegate.serialize_u32(v) 824 | } 825 | 826 | fn serialize_u64(self, v: u64) -> Result { 827 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 828 | self.delegate.serialize_u64(v) 829 | } 830 | 831 | fn serialize_u128(self, v: u128) -> Result { 832 | self.out.set(Some(itoa::Buffer::new().format(v).to_owned())); 833 | self.delegate.serialize_u128(v) 834 | } 835 | 836 | fn serialize_f32(self, v: f32) -> Result { 837 | self.delegate.serialize_f32(v) 838 | } 839 | 840 | fn serialize_f64(self, v: f64) -> Result { 841 | self.delegate.serialize_f64(v) 842 | } 843 | 844 | fn serialize_char(self, v: char) -> Result { 845 | self.delegate.serialize_char(v) 846 | } 847 | 848 | fn serialize_str(self, v: &str) -> Result { 849 | self.out.set(Some(v.to_owned())); 850 | self.delegate.serialize_str(v) 851 | } 852 | 853 | fn serialize_bytes(self, v: &[u8]) -> Result { 854 | self.delegate.serialize_bytes(v) 855 | } 856 | 857 | fn serialize_none(self) -> Result { 858 | self.delegate.serialize_none() 859 | } 860 | 861 | fn serialize_some(self, value: &T) -> Result 862 | where 863 | T: ?Sized + Serialize, 864 | { 865 | self.delegate 866 | .serialize_some(&CaptureKey::new(self.out, value)) 867 | } 868 | 869 | fn serialize_unit(self) -> Result { 870 | self.delegate.serialize_unit() 871 | } 872 | 873 | fn serialize_unit_struct(self, name: &'static str) -> Result { 874 | self.delegate.serialize_unit_struct(name) 875 | } 876 | 877 | fn serialize_unit_variant( 878 | self, 879 | name: &'static str, 880 | variant_index: u32, 881 | variant: &'static str, 882 | ) -> Result { 883 | self.out.set(Some(variant.to_owned())); 884 | self.delegate 885 | .serialize_unit_variant(name, variant_index, variant) 886 | } 887 | 888 | fn serialize_newtype_struct( 889 | self, 890 | name: &'static str, 891 | value: &T, 892 | ) -> Result 893 | where 894 | T: ?Sized + Serialize, 895 | { 896 | self.delegate 897 | .serialize_newtype_struct(name, &CaptureKey::new(self.out, value)) 898 | } 899 | 900 | fn serialize_newtype_variant( 901 | self, 902 | name: &'static str, 903 | variant_index: u32, 904 | variant: &'static str, 905 | value: &T, 906 | ) -> Result 907 | where 908 | T: ?Sized + Serialize, 909 | { 910 | self.delegate 911 | .serialize_newtype_variant(name, variant_index, variant, value) 912 | } 913 | 914 | fn serialize_seq(self, len: Option) -> Result { 915 | self.delegate.serialize_seq(len) 916 | } 917 | 918 | fn serialize_tuple(self, len: usize) -> Result { 919 | self.delegate.serialize_tuple(len) 920 | } 921 | 922 | fn serialize_tuple_struct( 923 | self, 924 | name: &'static str, 925 | len: usize, 926 | ) -> Result { 927 | self.delegate.serialize_tuple_struct(name, len) 928 | } 929 | 930 | fn serialize_tuple_variant( 931 | self, 932 | name: &'static str, 933 | variant_index: u32, 934 | variant: &'static str, 935 | len: usize, 936 | ) -> Result { 937 | self.delegate 938 | .serialize_tuple_variant(name, variant_index, variant, len) 939 | } 940 | 941 | fn serialize_map(self, len: Option) -> Result { 942 | self.delegate.serialize_map(len) 943 | } 944 | 945 | fn serialize_struct( 946 | self, 947 | name: &'static str, 948 | len: usize, 949 | ) -> Result { 950 | self.delegate.serialize_struct(name, len) 951 | } 952 | 953 | fn serialize_struct_variant( 954 | self, 955 | name: &'static str, 956 | variant_index: u32, 957 | variant: &'static str, 958 | len: usize, 959 | ) -> Result { 960 | self.delegate 961 | .serialize_struct_variant(name, variant_index, variant, len) 962 | } 963 | 964 | fn collect_seq(self, iter: I) -> Result 965 | where 966 | I: IntoIterator, 967 | I::Item: Serialize, 968 | { 969 | self.delegate.collect_seq(iter) 970 | } 971 | 972 | fn collect_map(self, iter: I) -> Result 973 | where 974 | K: Serialize, 975 | V: Serialize, 976 | I: IntoIterator, 977 | { 978 | self.delegate.collect_map(iter) 979 | } 980 | 981 | fn collect_str(self, value: &T) -> Result 982 | where 983 | T: ?Sized + Display, 984 | { 985 | self.out.set(Some(value.to_string())); 986 | self.delegate.collect_str(value) 987 | } 988 | 989 | fn is_human_readable(&self) -> bool { 990 | self.delegate.is_human_readable() 991 | } 992 | } 993 | -------------------------------------------------------------------------------- /src/de.rs: -------------------------------------------------------------------------------- 1 | use crate::wrap::{Wrap, WrapVariant}; 2 | use crate::{Chain, Error, Track}; 3 | use alloc::borrow::ToOwned as _; 4 | use alloc::string::String; 5 | use alloc::vec::Vec; 6 | use core::fmt; 7 | use serde::de::{self, Deserialize, DeserializeSeed, Visitor}; 8 | 9 | /// Entry point. See [crate documentation][crate] for an example. 10 | pub fn deserialize<'de, D, T>(deserializer: D) -> Result> 11 | where 12 | D: de::Deserializer<'de>, 13 | T: Deserialize<'de>, 14 | { 15 | let mut track = Track::new(); 16 | match T::deserialize(Deserializer::new(deserializer, &mut track)) { 17 | Ok(t) => Ok(t), 18 | Err(err) => Err(Error { 19 | path: track.path(), 20 | original: err, 21 | }), 22 | } 23 | } 24 | 25 | /// Deserializer adapter that records path to deserialization errors. 26 | /// 27 | /// # Example 28 | /// 29 | /// ``` 30 | /// # use serde_derive::Deserialize; 31 | /// # 32 | /// use serde::Deserialize; 33 | /// use std::collections::BTreeMap as Map; 34 | /// 35 | /// #[derive(Deserialize)] 36 | /// struct Package { 37 | /// name: String, 38 | /// dependencies: Map, 39 | /// } 40 | /// 41 | /// #[derive(Deserialize)] 42 | /// struct Dependency { 43 | /// version: String, 44 | /// } 45 | /// 46 | /// fn main() { 47 | /// let j = r#"{ 48 | /// "name": "demo", 49 | /// "dependencies": { 50 | /// "serde": { 51 | /// "version": 1 52 | /// } 53 | /// } 54 | /// }"#; 55 | /// 56 | /// // Some Deserializer. 57 | /// let jd = &mut serde_json::Deserializer::from_str(j); 58 | /// 59 | /// let mut track = serde_path_to_error::Track::new(); 60 | /// let pd = serde_path_to_error::Deserializer::new(jd, &mut track); 61 | /// 62 | /// match Package::deserialize(pd) { 63 | /// Ok(_) => panic!("expected a type error"), 64 | /// Err(_) => { 65 | /// let path = track.path().to_string(); 66 | /// assert_eq!(path, "dependencies.serde.version"); 67 | /// } 68 | /// } 69 | /// } 70 | /// ``` 71 | pub struct Deserializer<'a, 'b, D> { 72 | de: D, 73 | chain: Chain<'a>, 74 | track: &'b Track, 75 | } 76 | 77 | impl<'a, 'b, D> Deserializer<'a, 'b, D> { 78 | #[allow(clippy::needless_pass_by_ref_mut)] 79 | pub fn new(de: D, track: &'b mut Track) -> Self { 80 | Deserializer { 81 | de, 82 | chain: Chain::Root, 83 | track, 84 | } 85 | } 86 | } 87 | 88 | // Plain old forwarding impl. 89 | impl<'a, 'b, 'de, D> de::Deserializer<'de> for Deserializer<'a, 'b, D> 90 | where 91 | D: de::Deserializer<'de>, 92 | { 93 | type Error = D::Error; 94 | 95 | fn deserialize_any(self, visitor: V) -> Result 96 | where 97 | V: Visitor<'de>, 98 | { 99 | let chain = self.chain; 100 | let track = self.track; 101 | self.de 102 | .deserialize_any(Wrap::new(visitor, &chain, track)) 103 | .map_err(|err| track.trigger(&chain, err)) 104 | } 105 | 106 | fn deserialize_bool(self, visitor: V) -> Result 107 | where 108 | V: Visitor<'de>, 109 | { 110 | let chain = self.chain; 111 | let track = self.track; 112 | self.de 113 | .deserialize_bool(Wrap::new(visitor, &chain, track)) 114 | .map_err(|err| track.trigger(&chain, err)) 115 | } 116 | 117 | fn deserialize_u8(self, visitor: V) -> Result 118 | where 119 | V: Visitor<'de>, 120 | { 121 | let chain = self.chain; 122 | let track = self.track; 123 | self.de 124 | .deserialize_u8(Wrap::new(visitor, &chain, track)) 125 | .map_err(|err| track.trigger(&chain, err)) 126 | } 127 | 128 | fn deserialize_u16(self, visitor: V) -> Result 129 | where 130 | V: Visitor<'de>, 131 | { 132 | let chain = self.chain; 133 | let track = self.track; 134 | self.de 135 | .deserialize_u16(Wrap::new(visitor, &chain, track)) 136 | .map_err(|err| track.trigger(&chain, err)) 137 | } 138 | 139 | fn deserialize_u32(self, visitor: V) -> Result 140 | where 141 | V: Visitor<'de>, 142 | { 143 | let chain = self.chain; 144 | let track = self.track; 145 | self.de 146 | .deserialize_u32(Wrap::new(visitor, &chain, track)) 147 | .map_err(|err| track.trigger(&chain, err)) 148 | } 149 | 150 | fn deserialize_u64(self, visitor: V) -> Result 151 | where 152 | V: Visitor<'de>, 153 | { 154 | let chain = self.chain; 155 | let track = self.track; 156 | self.de 157 | .deserialize_u64(Wrap::new(visitor, &chain, track)) 158 | .map_err(|err| track.trigger(&chain, err)) 159 | } 160 | 161 | fn deserialize_u128(self, visitor: V) -> Result 162 | where 163 | V: Visitor<'de>, 164 | { 165 | let chain = self.chain; 166 | let track = self.track; 167 | self.de 168 | .deserialize_u128(Wrap::new(visitor, &chain, track)) 169 | .map_err(|err| track.trigger(&chain, err)) 170 | } 171 | 172 | fn deserialize_i8(self, visitor: V) -> Result 173 | where 174 | V: Visitor<'de>, 175 | { 176 | let chain = self.chain; 177 | let track = self.track; 178 | self.de 179 | .deserialize_i8(Wrap::new(visitor, &chain, track)) 180 | .map_err(|err| track.trigger(&chain, err)) 181 | } 182 | 183 | fn deserialize_i16(self, visitor: V) -> Result 184 | where 185 | V: Visitor<'de>, 186 | { 187 | let chain = self.chain; 188 | let track = self.track; 189 | self.de 190 | .deserialize_i16(Wrap::new(visitor, &chain, track)) 191 | .map_err(|err| track.trigger(&chain, err)) 192 | } 193 | 194 | fn deserialize_i32(self, visitor: V) -> Result 195 | where 196 | V: Visitor<'de>, 197 | { 198 | let chain = self.chain; 199 | let track = self.track; 200 | self.de 201 | .deserialize_i32(Wrap::new(visitor, &chain, track)) 202 | .map_err(|err| track.trigger(&chain, err)) 203 | } 204 | 205 | fn deserialize_i64(self, visitor: V) -> Result 206 | where 207 | V: Visitor<'de>, 208 | { 209 | let chain = self.chain; 210 | let track = self.track; 211 | self.de 212 | .deserialize_i64(Wrap::new(visitor, &chain, track)) 213 | .map_err(|err| track.trigger(&chain, err)) 214 | } 215 | 216 | fn deserialize_i128(self, visitor: V) -> Result 217 | where 218 | V: Visitor<'de>, 219 | { 220 | let chain = self.chain; 221 | let track = self.track; 222 | self.de 223 | .deserialize_i128(Wrap::new(visitor, &chain, track)) 224 | .map_err(|err| track.trigger(&chain, err)) 225 | } 226 | 227 | fn deserialize_f32(self, visitor: V) -> Result 228 | where 229 | V: Visitor<'de>, 230 | { 231 | let chain = self.chain; 232 | let track = self.track; 233 | self.de 234 | .deserialize_f32(Wrap::new(visitor, &chain, track)) 235 | .map_err(|err| track.trigger(&chain, err)) 236 | } 237 | 238 | fn deserialize_f64(self, visitor: V) -> Result 239 | where 240 | V: Visitor<'de>, 241 | { 242 | let chain = self.chain; 243 | let track = self.track; 244 | self.de 245 | .deserialize_f64(Wrap::new(visitor, &chain, track)) 246 | .map_err(|err| track.trigger(&chain, err)) 247 | } 248 | 249 | fn deserialize_char(self, visitor: V) -> Result 250 | where 251 | V: Visitor<'de>, 252 | { 253 | let chain = self.chain; 254 | let track = self.track; 255 | self.de 256 | .deserialize_char(Wrap::new(visitor, &chain, track)) 257 | .map_err(|err| track.trigger(&chain, err)) 258 | } 259 | 260 | fn deserialize_str(self, visitor: V) -> Result 261 | where 262 | V: Visitor<'de>, 263 | { 264 | let chain = self.chain; 265 | let track = self.track; 266 | self.de 267 | .deserialize_str(Wrap::new(visitor, &chain, track)) 268 | .map_err(|err| track.trigger(&chain, err)) 269 | } 270 | 271 | fn deserialize_string(self, visitor: V) -> Result 272 | where 273 | V: Visitor<'de>, 274 | { 275 | let chain = self.chain; 276 | let track = self.track; 277 | self.de 278 | .deserialize_string(Wrap::new(visitor, &chain, track)) 279 | .map_err(|err| track.trigger(&chain, err)) 280 | } 281 | 282 | fn deserialize_bytes(self, visitor: V) -> Result 283 | where 284 | V: Visitor<'de>, 285 | { 286 | let chain = self.chain; 287 | let track = self.track; 288 | self.de 289 | .deserialize_bytes(Wrap::new(visitor, &chain, track)) 290 | .map_err(|err| track.trigger(&chain, err)) 291 | } 292 | 293 | fn deserialize_byte_buf(self, visitor: V) -> Result 294 | where 295 | V: Visitor<'de>, 296 | { 297 | let chain = self.chain; 298 | let track = self.track; 299 | self.de 300 | .deserialize_byte_buf(Wrap::new(visitor, &chain, track)) 301 | .map_err(|err| track.trigger(&chain, err)) 302 | } 303 | 304 | fn deserialize_option(self, visitor: V) -> Result 305 | where 306 | V: Visitor<'de>, 307 | { 308 | let chain = self.chain; 309 | let track = self.track; 310 | self.de 311 | .deserialize_option(Wrap::new(visitor, &chain, track)) 312 | .map_err(|err| track.trigger(&chain, err)) 313 | } 314 | 315 | fn deserialize_unit(self, visitor: V) -> Result 316 | where 317 | V: Visitor<'de>, 318 | { 319 | let chain = self.chain; 320 | let track = self.track; 321 | self.de 322 | .deserialize_unit(Wrap::new(visitor, &chain, track)) 323 | .map_err(|err| track.trigger(&chain, err)) 324 | } 325 | 326 | fn deserialize_unit_struct( 327 | self, 328 | name: &'static str, 329 | visitor: V, 330 | ) -> Result 331 | where 332 | V: Visitor<'de>, 333 | { 334 | let chain = self.chain; 335 | let track = self.track; 336 | self.de 337 | .deserialize_unit_struct(name, Wrap::new(visitor, &chain, track)) 338 | .map_err(|err| track.trigger(&chain, err)) 339 | } 340 | 341 | fn deserialize_newtype_struct( 342 | self, 343 | name: &'static str, 344 | visitor: V, 345 | ) -> Result 346 | where 347 | V: Visitor<'de>, 348 | { 349 | let chain = self.chain; 350 | let track = self.track; 351 | self.de 352 | .deserialize_newtype_struct(name, Wrap::new(visitor, &chain, track)) 353 | .map_err(|err| track.trigger(&chain, err)) 354 | } 355 | 356 | fn deserialize_seq(self, visitor: V) -> Result 357 | where 358 | V: Visitor<'de>, 359 | { 360 | let chain = self.chain; 361 | let track = self.track; 362 | self.de 363 | .deserialize_seq(Wrap::new(visitor, &chain, track)) 364 | .map_err(|err| track.trigger(&chain, err)) 365 | } 366 | 367 | fn deserialize_tuple(self, len: usize, visitor: V) -> Result 368 | where 369 | V: Visitor<'de>, 370 | { 371 | let chain = self.chain; 372 | let track = self.track; 373 | self.de 374 | .deserialize_tuple(len, Wrap::new(visitor, &chain, track)) 375 | .map_err(|err| track.trigger(&chain, err)) 376 | } 377 | 378 | fn deserialize_tuple_struct( 379 | self, 380 | name: &'static str, 381 | len: usize, 382 | visitor: V, 383 | ) -> Result 384 | where 385 | V: Visitor<'de>, 386 | { 387 | let chain = self.chain; 388 | let track = self.track; 389 | self.de 390 | .deserialize_tuple_struct(name, len, Wrap::new(visitor, &chain, track)) 391 | .map_err(|err| track.trigger(&chain, err)) 392 | } 393 | 394 | fn deserialize_map(self, visitor: V) -> Result 395 | where 396 | V: Visitor<'de>, 397 | { 398 | let chain = self.chain; 399 | let track = self.track; 400 | self.de 401 | .deserialize_map(Wrap::new(visitor, &chain, track)) 402 | .map_err(|err| track.trigger(&chain, err)) 403 | } 404 | 405 | fn deserialize_struct( 406 | self, 407 | name: &'static str, 408 | fields: &'static [&'static str], 409 | visitor: V, 410 | ) -> Result 411 | where 412 | V: Visitor<'de>, 413 | { 414 | let chain = self.chain; 415 | let track = self.track; 416 | self.de 417 | .deserialize_struct(name, fields, Wrap::new(visitor, &chain, track)) 418 | .map_err(|err| track.trigger(&chain, err)) 419 | } 420 | 421 | fn deserialize_enum( 422 | self, 423 | name: &'static str, 424 | variants: &'static [&'static str], 425 | visitor: V, 426 | ) -> Result 427 | where 428 | V: Visitor<'de>, 429 | { 430 | let chain = self.chain; 431 | let track = self.track; 432 | self.de 433 | .deserialize_enum(name, variants, Wrap::new(visitor, &chain, track)) 434 | .map_err(|err| track.trigger(&chain, err)) 435 | } 436 | 437 | fn deserialize_ignored_any(self, visitor: V) -> Result 438 | where 439 | V: Visitor<'de>, 440 | { 441 | let chain = self.chain; 442 | let track = self.track; 443 | self.de 444 | .deserialize_ignored_any(Wrap::new(visitor, &chain, track)) 445 | .map_err(|err| track.trigger(&chain, err)) 446 | } 447 | 448 | fn deserialize_identifier(self, visitor: V) -> Result 449 | where 450 | V: Visitor<'de>, 451 | { 452 | let chain = self.chain; 453 | let track = self.track; 454 | self.de 455 | .deserialize_identifier(Wrap::new(visitor, &chain, track)) 456 | .map_err(|err| track.trigger(&chain, err)) 457 | } 458 | 459 | fn is_human_readable(&self) -> bool { 460 | self.de.is_human_readable() 461 | } 462 | } 463 | 464 | // Forwarding impl to preserve context. 465 | impl<'a, 'b, 'de, X> Visitor<'de> for Wrap<'a, 'b, X> 466 | where 467 | X: Visitor<'de>, 468 | { 469 | type Value = X::Value; 470 | 471 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 472 | self.delegate.expecting(formatter) 473 | } 474 | 475 | fn visit_bool(self, v: bool) -> Result 476 | where 477 | E: de::Error, 478 | { 479 | let chain = self.chain; 480 | let track = self.track; 481 | self.delegate 482 | .visit_bool(v) 483 | .map_err(|err| track.trigger(chain, err)) 484 | } 485 | 486 | fn visit_i8(self, v: i8) -> Result 487 | where 488 | E: de::Error, 489 | { 490 | let chain = self.chain; 491 | let track = self.track; 492 | self.delegate 493 | .visit_i8(v) 494 | .map_err(|err| track.trigger(chain, err)) 495 | } 496 | 497 | fn visit_i16(self, v: i16) -> Result 498 | where 499 | E: de::Error, 500 | { 501 | let chain = self.chain; 502 | let track = self.track; 503 | self.delegate 504 | .visit_i16(v) 505 | .map_err(|err| track.trigger(chain, err)) 506 | } 507 | 508 | fn visit_i32(self, v: i32) -> Result 509 | where 510 | E: de::Error, 511 | { 512 | let chain = self.chain; 513 | let track = self.track; 514 | self.delegate 515 | .visit_i32(v) 516 | .map_err(|err| track.trigger(chain, err)) 517 | } 518 | 519 | fn visit_i64(self, v: i64) -> Result 520 | where 521 | E: de::Error, 522 | { 523 | let chain = self.chain; 524 | let track = self.track; 525 | self.delegate 526 | .visit_i64(v) 527 | .map_err(|err| track.trigger(chain, err)) 528 | } 529 | 530 | fn visit_i128(self, v: i128) -> Result 531 | where 532 | E: de::Error, 533 | { 534 | let chain = self.chain; 535 | let track = self.track; 536 | self.delegate 537 | .visit_i128(v) 538 | .map_err(|err| track.trigger(chain, err)) 539 | } 540 | 541 | fn visit_u8(self, v: u8) -> Result 542 | where 543 | E: de::Error, 544 | { 545 | let chain = self.chain; 546 | let track = self.track; 547 | self.delegate 548 | .visit_u8(v) 549 | .map_err(|err| track.trigger(chain, err)) 550 | } 551 | 552 | fn visit_u16(self, v: u16) -> Result 553 | where 554 | E: de::Error, 555 | { 556 | let chain = self.chain; 557 | let track = self.track; 558 | self.delegate 559 | .visit_u16(v) 560 | .map_err(|err| track.trigger(chain, err)) 561 | } 562 | 563 | fn visit_u32(self, v: u32) -> Result 564 | where 565 | E: de::Error, 566 | { 567 | let chain = self.chain; 568 | let track = self.track; 569 | self.delegate 570 | .visit_u32(v) 571 | .map_err(|err| track.trigger(chain, err)) 572 | } 573 | 574 | fn visit_u64(self, v: u64) -> Result 575 | where 576 | E: de::Error, 577 | { 578 | let chain = self.chain; 579 | let track = self.track; 580 | self.delegate 581 | .visit_u64(v) 582 | .map_err(|err| track.trigger(chain, err)) 583 | } 584 | 585 | fn visit_u128(self, v: u128) -> Result 586 | where 587 | E: de::Error, 588 | { 589 | let chain = self.chain; 590 | let track = self.track; 591 | self.delegate 592 | .visit_u128(v) 593 | .map_err(|err| track.trigger(chain, err)) 594 | } 595 | 596 | fn visit_f32(self, v: f32) -> Result 597 | where 598 | E: de::Error, 599 | { 600 | let chain = self.chain; 601 | let track = self.track; 602 | self.delegate 603 | .visit_f32(v) 604 | .map_err(|err| track.trigger(chain, err)) 605 | } 606 | 607 | fn visit_f64(self, v: f64) -> Result 608 | where 609 | E: de::Error, 610 | { 611 | let chain = self.chain; 612 | let track = self.track; 613 | self.delegate 614 | .visit_f64(v) 615 | .map_err(|err| track.trigger(chain, err)) 616 | } 617 | 618 | fn visit_char(self, v: char) -> Result 619 | where 620 | E: de::Error, 621 | { 622 | let chain = self.chain; 623 | let track = self.track; 624 | self.delegate 625 | .visit_char(v) 626 | .map_err(|err| track.trigger(chain, err)) 627 | } 628 | 629 | fn visit_str(self, v: &str) -> Result 630 | where 631 | E: de::Error, 632 | { 633 | let chain = self.chain; 634 | let track = self.track; 635 | self.delegate 636 | .visit_str(v) 637 | .map_err(|err| track.trigger(chain, err)) 638 | } 639 | 640 | fn visit_borrowed_str(self, v: &'de str) -> Result 641 | where 642 | E: de::Error, 643 | { 644 | let chain = self.chain; 645 | let track = self.track; 646 | self.delegate 647 | .visit_borrowed_str(v) 648 | .map_err(|err| track.trigger(chain, err)) 649 | } 650 | 651 | fn visit_string(self, v: String) -> Result 652 | where 653 | E: de::Error, 654 | { 655 | let chain = self.chain; 656 | let track = self.track; 657 | self.delegate 658 | .visit_string(v) 659 | .map_err(|err| track.trigger(chain, err)) 660 | } 661 | 662 | fn visit_unit(self) -> Result 663 | where 664 | E: de::Error, 665 | { 666 | let chain = self.chain; 667 | let track = self.track; 668 | self.delegate 669 | .visit_unit() 670 | .map_err(|err| track.trigger(chain, err)) 671 | } 672 | 673 | fn visit_none(self) -> Result 674 | where 675 | E: de::Error, 676 | { 677 | let chain = self.chain; 678 | let track = self.track; 679 | self.delegate 680 | .visit_none() 681 | .map_err(|err| track.trigger(chain, err)) 682 | } 683 | 684 | fn visit_some(self, deserializer: D) -> Result 685 | where 686 | D: de::Deserializer<'de>, 687 | { 688 | let chain = self.chain; 689 | let track = self.track; 690 | self.delegate 691 | .visit_some(Deserializer { 692 | de: deserializer, 693 | chain: Chain::Some { parent: chain }, 694 | track, 695 | }) 696 | .map_err(|err| track.trigger(chain, err)) 697 | } 698 | 699 | fn visit_newtype_struct(self, deserializer: D) -> Result 700 | where 701 | D: de::Deserializer<'de>, 702 | { 703 | let chain = self.chain; 704 | let track = self.track; 705 | self.delegate 706 | .visit_newtype_struct(Deserializer { 707 | de: deserializer, 708 | chain: Chain::NewtypeStruct { parent: chain }, 709 | track, 710 | }) 711 | .map_err(|err| track.trigger(chain, err)) 712 | } 713 | 714 | fn visit_seq(self, visitor: V) -> Result 715 | where 716 | V: de::SeqAccess<'de>, 717 | { 718 | let chain = self.chain; 719 | let track = self.track; 720 | self.delegate 721 | .visit_seq(SeqAccess::new(visitor, chain, track)) 722 | .map_err(|err| track.trigger(chain, err)) 723 | } 724 | 725 | fn visit_map(self, visitor: V) -> Result 726 | where 727 | V: de::MapAccess<'de>, 728 | { 729 | let chain = self.chain; 730 | let track = self.track; 731 | self.delegate 732 | .visit_map(MapAccess::new(visitor, chain, track)) 733 | .map_err(|err| track.trigger(chain, err)) 734 | } 735 | 736 | fn visit_enum(self, visitor: V) -> Result 737 | where 738 | V: de::EnumAccess<'de>, 739 | { 740 | let chain = self.chain; 741 | let track = self.track; 742 | self.delegate 743 | .visit_enum(Wrap::new(visitor, chain, track)) 744 | .map_err(|err| track.trigger(chain, err)) 745 | } 746 | 747 | fn visit_bytes(self, v: &[u8]) -> Result 748 | where 749 | E: de::Error, 750 | { 751 | let chain = self.chain; 752 | let track = self.track; 753 | self.delegate 754 | .visit_bytes(v) 755 | .map_err(|err| track.trigger(chain, err)) 756 | } 757 | 758 | fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result 759 | where 760 | E: de::Error, 761 | { 762 | let chain = self.chain; 763 | let track = self.track; 764 | self.delegate 765 | .visit_borrowed_bytes(v) 766 | .map_err(|err| track.trigger(chain, err)) 767 | } 768 | 769 | fn visit_byte_buf(self, v: Vec) -> Result 770 | where 771 | E: de::Error, 772 | { 773 | let chain = self.chain; 774 | let track = self.track; 775 | self.delegate 776 | .visit_byte_buf(v) 777 | .map_err(|err| track.trigger(chain, err)) 778 | } 779 | } 780 | 781 | // Forwarding impl to preserve context. 782 | impl<'a, 'b, 'de, X> de::EnumAccess<'de> for Wrap<'a, 'b, X> 783 | where 784 | X: de::EnumAccess<'de> + 'a, 785 | { 786 | type Error = X::Error; 787 | type Variant = WrapVariant<'a, 'b, X::Variant>; 788 | 789 | fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), X::Error> 790 | where 791 | V: DeserializeSeed<'de>, 792 | { 793 | let chain = self.chain; 794 | let track = self.track; 795 | let mut variant = None; 796 | self.delegate 797 | .variant_seed(CaptureKey::new(seed, &mut variant)) 798 | .map_err(|err| track.trigger(chain, err)) 799 | .map(move |(v, vis)| { 800 | let chain = match variant { 801 | Some(variant) => Chain::Enum { 802 | parent: chain, 803 | variant, 804 | }, 805 | None => Chain::NonStringKey { parent: chain }, 806 | }; 807 | (v, WrapVariant::new(vis, chain, track)) 808 | }) 809 | } 810 | } 811 | 812 | // Forwarding impl to preserve context. 813 | impl<'a, 'b, 'de, X> de::VariantAccess<'de> for WrapVariant<'a, 'b, X> 814 | where 815 | X: de::VariantAccess<'de>, 816 | { 817 | type Error = X::Error; 818 | 819 | fn unit_variant(self) -> Result<(), X::Error> { 820 | let chain = self.chain; 821 | let track = self.track; 822 | self.delegate 823 | .unit_variant() 824 | .map_err(|err| track.trigger(&chain, err)) 825 | } 826 | 827 | fn newtype_variant_seed(self, seed: T) -> Result 828 | where 829 | T: DeserializeSeed<'de>, 830 | { 831 | let chain = self.chain; 832 | let track = self.track; 833 | let nested = Chain::NewtypeVariant { parent: &chain }; 834 | self.delegate 835 | .newtype_variant_seed(TrackedSeed::new(seed, nested, track)) 836 | .map_err(|err| track.trigger(&chain, err)) 837 | } 838 | 839 | fn tuple_variant(self, len: usize, visitor: V) -> Result 840 | where 841 | V: Visitor<'de>, 842 | { 843 | let chain = self.chain; 844 | let track = self.track; 845 | self.delegate 846 | .tuple_variant(len, Wrap::new(visitor, &chain, track)) 847 | .map_err(|err| track.trigger(&chain, err)) 848 | } 849 | 850 | fn struct_variant( 851 | self, 852 | fields: &'static [&'static str], 853 | visitor: V, 854 | ) -> Result 855 | where 856 | V: Visitor<'de>, 857 | { 858 | let chain = self.chain; 859 | let track = self.track; 860 | self.delegate 861 | .struct_variant(fields, Wrap::new(visitor, &chain, track)) 862 | .map_err(|err| track.trigger(&chain, err)) 863 | } 864 | } 865 | 866 | // Seed that saves the string into the given optional during `visit_str` and 867 | // `visit_string`. 868 | struct CaptureKey<'a, X> { 869 | delegate: X, 870 | key: &'a mut Option, 871 | } 872 | 873 | impl<'a, X> CaptureKey<'a, X> { 874 | fn new(delegate: X, key: &'a mut Option) -> Self { 875 | CaptureKey { delegate, key } 876 | } 877 | } 878 | 879 | // Forwarding impl. 880 | impl<'a, 'de, X> DeserializeSeed<'de> for CaptureKey<'a, X> 881 | where 882 | X: DeserializeSeed<'de>, 883 | { 884 | type Value = X::Value; 885 | 886 | fn deserialize(self, deserializer: D) -> Result 887 | where 888 | D: de::Deserializer<'de>, 889 | { 890 | self.delegate 891 | .deserialize(CaptureKey::new(deserializer, self.key)) 892 | } 893 | } 894 | 895 | // Forwarding impl. 896 | impl<'a, 'de, X> de::Deserializer<'de> for CaptureKey<'a, X> 897 | where 898 | X: de::Deserializer<'de>, 899 | { 900 | type Error = X::Error; 901 | 902 | fn deserialize_any(self, visitor: V) -> Result 903 | where 904 | V: Visitor<'de>, 905 | { 906 | self.delegate 907 | .deserialize_any(CaptureKey::new(visitor, self.key)) 908 | } 909 | 910 | fn deserialize_bool(self, visitor: V) -> Result 911 | where 912 | V: Visitor<'de>, 913 | { 914 | self.delegate 915 | .deserialize_bool(CaptureKey::new(visitor, self.key)) 916 | } 917 | 918 | fn deserialize_u8(self, visitor: V) -> Result 919 | where 920 | V: Visitor<'de>, 921 | { 922 | self.delegate 923 | .deserialize_u8(CaptureKey::new(visitor, self.key)) 924 | } 925 | 926 | fn deserialize_u16(self, visitor: V) -> Result 927 | where 928 | V: Visitor<'de>, 929 | { 930 | self.delegate 931 | .deserialize_u16(CaptureKey::new(visitor, self.key)) 932 | } 933 | 934 | fn deserialize_u32(self, visitor: V) -> Result 935 | where 936 | V: Visitor<'de>, 937 | { 938 | self.delegate 939 | .deserialize_u32(CaptureKey::new(visitor, self.key)) 940 | } 941 | 942 | fn deserialize_u64(self, visitor: V) -> Result 943 | where 944 | V: Visitor<'de>, 945 | { 946 | self.delegate 947 | .deserialize_u64(CaptureKey::new(visitor, self.key)) 948 | } 949 | 950 | fn deserialize_u128(self, visitor: V) -> Result 951 | where 952 | V: Visitor<'de>, 953 | { 954 | self.delegate 955 | .deserialize_u128(CaptureKey::new(visitor, self.key)) 956 | } 957 | 958 | fn deserialize_i8(self, visitor: V) -> Result 959 | where 960 | V: Visitor<'de>, 961 | { 962 | self.delegate 963 | .deserialize_i8(CaptureKey::new(visitor, self.key)) 964 | } 965 | 966 | fn deserialize_i16(self, visitor: V) -> Result 967 | where 968 | V: Visitor<'de>, 969 | { 970 | self.delegate 971 | .deserialize_i16(CaptureKey::new(visitor, self.key)) 972 | } 973 | 974 | fn deserialize_i32(self, visitor: V) -> Result 975 | where 976 | V: Visitor<'de>, 977 | { 978 | self.delegate 979 | .deserialize_i32(CaptureKey::new(visitor, self.key)) 980 | } 981 | 982 | fn deserialize_i64(self, visitor: V) -> Result 983 | where 984 | V: Visitor<'de>, 985 | { 986 | self.delegate 987 | .deserialize_i64(CaptureKey::new(visitor, self.key)) 988 | } 989 | 990 | fn deserialize_i128(self, visitor: V) -> Result 991 | where 992 | V: Visitor<'de>, 993 | { 994 | self.delegate 995 | .deserialize_i128(CaptureKey::new(visitor, self.key)) 996 | } 997 | 998 | fn deserialize_f32(self, visitor: V) -> Result 999 | where 1000 | V: Visitor<'de>, 1001 | { 1002 | self.delegate 1003 | .deserialize_f32(CaptureKey::new(visitor, self.key)) 1004 | } 1005 | 1006 | fn deserialize_f64(self, visitor: V) -> Result 1007 | where 1008 | V: Visitor<'de>, 1009 | { 1010 | self.delegate 1011 | .deserialize_f64(CaptureKey::new(visitor, self.key)) 1012 | } 1013 | 1014 | fn deserialize_char(self, visitor: V) -> Result 1015 | where 1016 | V: Visitor<'de>, 1017 | { 1018 | self.delegate 1019 | .deserialize_char(CaptureKey::new(visitor, self.key)) 1020 | } 1021 | 1022 | fn deserialize_str(self, visitor: V) -> Result 1023 | where 1024 | V: Visitor<'de>, 1025 | { 1026 | self.delegate 1027 | .deserialize_str(CaptureKey::new(visitor, self.key)) 1028 | } 1029 | 1030 | fn deserialize_string(self, visitor: V) -> Result 1031 | where 1032 | V: Visitor<'de>, 1033 | { 1034 | self.delegate 1035 | .deserialize_string(CaptureKey::new(visitor, self.key)) 1036 | } 1037 | 1038 | fn deserialize_bytes(self, visitor: V) -> Result 1039 | where 1040 | V: Visitor<'de>, 1041 | { 1042 | self.delegate 1043 | .deserialize_bytes(CaptureKey::new(visitor, self.key)) 1044 | } 1045 | 1046 | fn deserialize_byte_buf(self, visitor: V) -> Result 1047 | where 1048 | V: Visitor<'de>, 1049 | { 1050 | self.delegate 1051 | .deserialize_byte_buf(CaptureKey::new(visitor, self.key)) 1052 | } 1053 | 1054 | fn deserialize_option(self, visitor: V) -> Result 1055 | where 1056 | V: Visitor<'de>, 1057 | { 1058 | self.delegate 1059 | .deserialize_option(CaptureKey::new(visitor, self.key)) 1060 | } 1061 | 1062 | fn deserialize_unit(self, visitor: V) -> Result 1063 | where 1064 | V: Visitor<'de>, 1065 | { 1066 | self.delegate 1067 | .deserialize_unit(CaptureKey::new(visitor, self.key)) 1068 | } 1069 | 1070 | fn deserialize_unit_struct( 1071 | self, 1072 | name: &'static str, 1073 | visitor: V, 1074 | ) -> Result 1075 | where 1076 | V: Visitor<'de>, 1077 | { 1078 | self.delegate 1079 | .deserialize_unit_struct(name, CaptureKey::new(visitor, self.key)) 1080 | } 1081 | 1082 | fn deserialize_newtype_struct( 1083 | self, 1084 | name: &'static str, 1085 | visitor: V, 1086 | ) -> Result 1087 | where 1088 | V: Visitor<'de>, 1089 | { 1090 | self.delegate 1091 | .deserialize_newtype_struct(name, CaptureKey::new(visitor, self.key)) 1092 | } 1093 | 1094 | fn deserialize_seq(self, visitor: V) -> Result 1095 | where 1096 | V: Visitor<'de>, 1097 | { 1098 | self.delegate 1099 | .deserialize_seq(CaptureKey::new(visitor, self.key)) 1100 | } 1101 | 1102 | fn deserialize_tuple(self, len: usize, visitor: V) -> Result 1103 | where 1104 | V: Visitor<'de>, 1105 | { 1106 | self.delegate 1107 | .deserialize_tuple(len, CaptureKey::new(visitor, self.key)) 1108 | } 1109 | 1110 | fn deserialize_tuple_struct( 1111 | self, 1112 | name: &'static str, 1113 | len: usize, 1114 | visitor: V, 1115 | ) -> Result 1116 | where 1117 | V: Visitor<'de>, 1118 | { 1119 | self.delegate 1120 | .deserialize_tuple_struct(name, len, CaptureKey::new(visitor, self.key)) 1121 | } 1122 | 1123 | fn deserialize_map(self, visitor: V) -> Result 1124 | where 1125 | V: Visitor<'de>, 1126 | { 1127 | self.delegate 1128 | .deserialize_map(CaptureKey::new(visitor, self.key)) 1129 | } 1130 | 1131 | fn deserialize_struct( 1132 | self, 1133 | name: &'static str, 1134 | fields: &'static [&'static str], 1135 | visitor: V, 1136 | ) -> Result 1137 | where 1138 | V: Visitor<'de>, 1139 | { 1140 | self.delegate 1141 | .deserialize_struct(name, fields, CaptureKey::new(visitor, self.key)) 1142 | } 1143 | 1144 | fn deserialize_enum( 1145 | self, 1146 | name: &'static str, 1147 | variants: &'static [&'static str], 1148 | visitor: V, 1149 | ) -> Result 1150 | where 1151 | V: Visitor<'de>, 1152 | { 1153 | self.delegate 1154 | .deserialize_enum(name, variants, CaptureKey::new(visitor, self.key)) 1155 | } 1156 | 1157 | fn deserialize_ignored_any(self, visitor: V) -> Result 1158 | where 1159 | V: Visitor<'de>, 1160 | { 1161 | self.delegate 1162 | .deserialize_ignored_any(CaptureKey::new(visitor, self.key)) 1163 | } 1164 | 1165 | fn deserialize_identifier(self, visitor: V) -> Result 1166 | where 1167 | V: Visitor<'de>, 1168 | { 1169 | self.delegate 1170 | .deserialize_identifier(CaptureKey::new(visitor, self.key)) 1171 | } 1172 | 1173 | fn is_human_readable(&self) -> bool { 1174 | self.delegate.is_human_readable() 1175 | } 1176 | } 1177 | 1178 | // Forwarding impl except `visit_str` and `visit_string` which save the string. 1179 | impl<'a, 'de, X> Visitor<'de> for CaptureKey<'a, X> 1180 | where 1181 | X: Visitor<'de>, 1182 | { 1183 | type Value = X::Value; 1184 | 1185 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 1186 | self.delegate.expecting(formatter) 1187 | } 1188 | 1189 | fn visit_bool(self, v: bool) -> Result 1190 | where 1191 | E: de::Error, 1192 | { 1193 | let string = if v { "true" } else { "false" }; 1194 | *self.key = Some(string.to_owned()); 1195 | self.delegate.visit_bool(v) 1196 | } 1197 | 1198 | fn visit_i8(self, v: i8) -> Result 1199 | where 1200 | E: de::Error, 1201 | { 1202 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1203 | self.delegate.visit_i8(v) 1204 | } 1205 | 1206 | fn visit_i16(self, v: i16) -> Result 1207 | where 1208 | E: de::Error, 1209 | { 1210 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1211 | self.delegate.visit_i16(v) 1212 | } 1213 | 1214 | fn visit_i32(self, v: i32) -> Result 1215 | where 1216 | E: de::Error, 1217 | { 1218 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1219 | self.delegate.visit_i32(v) 1220 | } 1221 | 1222 | fn visit_i64(self, v: i64) -> Result 1223 | where 1224 | E: de::Error, 1225 | { 1226 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1227 | self.delegate.visit_i64(v) 1228 | } 1229 | 1230 | fn visit_i128(self, v: i128) -> Result 1231 | where 1232 | E: de::Error, 1233 | { 1234 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1235 | self.delegate.visit_i128(v) 1236 | } 1237 | 1238 | fn visit_u8(self, v: u8) -> Result 1239 | where 1240 | E: de::Error, 1241 | { 1242 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1243 | self.delegate.visit_u8(v) 1244 | } 1245 | 1246 | fn visit_u16(self, v: u16) -> Result 1247 | where 1248 | E: de::Error, 1249 | { 1250 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1251 | self.delegate.visit_u16(v) 1252 | } 1253 | 1254 | fn visit_u32(self, v: u32) -> Result 1255 | where 1256 | E: de::Error, 1257 | { 1258 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1259 | self.delegate.visit_u32(v) 1260 | } 1261 | 1262 | fn visit_u64(self, v: u64) -> Result 1263 | where 1264 | E: de::Error, 1265 | { 1266 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1267 | self.delegate.visit_u64(v) 1268 | } 1269 | 1270 | fn visit_u128(self, v: u128) -> Result 1271 | where 1272 | E: de::Error, 1273 | { 1274 | *self.key = Some(itoa::Buffer::new().format(v).to_owned()); 1275 | self.delegate.visit_u128(v) 1276 | } 1277 | 1278 | fn visit_f32(self, v: f32) -> Result 1279 | where 1280 | E: de::Error, 1281 | { 1282 | self.delegate.visit_f32(v) 1283 | } 1284 | 1285 | fn visit_f64(self, v: f64) -> Result 1286 | where 1287 | E: de::Error, 1288 | { 1289 | self.delegate.visit_f64(v) 1290 | } 1291 | 1292 | fn visit_char(self, v: char) -> Result 1293 | where 1294 | E: de::Error, 1295 | { 1296 | self.delegate.visit_char(v) 1297 | } 1298 | 1299 | fn visit_str(self, v: &str) -> Result 1300 | where 1301 | E: de::Error, 1302 | { 1303 | *self.key = Some(v.to_owned()); 1304 | self.delegate.visit_str(v) 1305 | } 1306 | 1307 | fn visit_borrowed_str(self, v: &'de str) -> Result 1308 | where 1309 | E: de::Error, 1310 | { 1311 | *self.key = Some(v.to_owned()); 1312 | self.delegate.visit_borrowed_str(v) 1313 | } 1314 | 1315 | fn visit_string(self, v: String) -> Result 1316 | where 1317 | E: de::Error, 1318 | { 1319 | *self.key = Some(v.clone()); 1320 | self.delegate.visit_string(v) 1321 | } 1322 | 1323 | fn visit_unit(self) -> Result 1324 | where 1325 | E: de::Error, 1326 | { 1327 | self.delegate.visit_unit() 1328 | } 1329 | 1330 | fn visit_none(self) -> Result 1331 | where 1332 | E: de::Error, 1333 | { 1334 | self.delegate.visit_none() 1335 | } 1336 | 1337 | fn visit_some(self, deserializer: D) -> Result 1338 | where 1339 | D: de::Deserializer<'de>, 1340 | { 1341 | self.delegate.visit_some(deserializer) 1342 | } 1343 | 1344 | fn visit_newtype_struct(self, deserializer: D) -> Result 1345 | where 1346 | D: de::Deserializer<'de>, 1347 | { 1348 | self.delegate.visit_newtype_struct(deserializer) 1349 | } 1350 | 1351 | fn visit_seq(self, visitor: V) -> Result 1352 | where 1353 | V: de::SeqAccess<'de>, 1354 | { 1355 | self.delegate.visit_seq(visitor) 1356 | } 1357 | 1358 | fn visit_map(self, visitor: V) -> Result 1359 | where 1360 | V: de::MapAccess<'de>, 1361 | { 1362 | self.delegate.visit_map(visitor) 1363 | } 1364 | 1365 | fn visit_enum(self, visitor: V) -> Result 1366 | where 1367 | V: de::EnumAccess<'de>, 1368 | { 1369 | self.delegate.visit_enum(visitor) 1370 | } 1371 | 1372 | fn visit_bytes(self, v: &[u8]) -> Result 1373 | where 1374 | E: de::Error, 1375 | { 1376 | self.delegate.visit_bytes(v) 1377 | } 1378 | 1379 | fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result 1380 | where 1381 | E: de::Error, 1382 | { 1383 | self.delegate.visit_borrowed_bytes(v) 1384 | } 1385 | 1386 | fn visit_byte_buf(self, v: Vec) -> Result 1387 | where 1388 | E: de::Error, 1389 | { 1390 | self.delegate.visit_byte_buf(v) 1391 | } 1392 | } 1393 | 1394 | // Seed used for map values, sequence elements and newtype variants to track 1395 | // their path. 1396 | struct TrackedSeed<'a, 'b, X> { 1397 | seed: X, 1398 | chain: Chain<'a>, 1399 | track: &'b Track, 1400 | } 1401 | 1402 | impl<'a, 'b, X> TrackedSeed<'a, 'b, X> { 1403 | fn new(seed: X, chain: Chain<'a>, track: &'b Track) -> Self { 1404 | TrackedSeed { seed, chain, track } 1405 | } 1406 | } 1407 | 1408 | impl<'a, 'b, 'de, X> DeserializeSeed<'de> for TrackedSeed<'a, 'b, X> 1409 | where 1410 | X: DeserializeSeed<'de>, 1411 | { 1412 | type Value = X::Value; 1413 | 1414 | fn deserialize(self, deserializer: D) -> Result 1415 | where 1416 | D: de::Deserializer<'de>, 1417 | { 1418 | let chain = self.chain; 1419 | let track = self.track; 1420 | self.seed 1421 | .deserialize(Deserializer { 1422 | de: deserializer, 1423 | chain: chain.clone(), 1424 | track, 1425 | }) 1426 | .map_err(|err| track.trigger(&chain, err)) 1427 | } 1428 | } 1429 | 1430 | // Seq visitor that tracks the index of its elements. 1431 | struct SeqAccess<'a, 'b, X> { 1432 | delegate: X, 1433 | chain: &'a Chain<'a>, 1434 | index: usize, 1435 | track: &'b Track, 1436 | } 1437 | 1438 | impl<'a, 'b, X> SeqAccess<'a, 'b, X> { 1439 | fn new(delegate: X, chain: &'a Chain<'a>, track: &'b Track) -> Self { 1440 | SeqAccess { 1441 | delegate, 1442 | chain, 1443 | index: 0, 1444 | track, 1445 | } 1446 | } 1447 | } 1448 | 1449 | // Forwarding impl to preserve context. 1450 | impl<'a, 'b, 'de, X> de::SeqAccess<'de> for SeqAccess<'a, 'b, X> 1451 | where 1452 | X: de::SeqAccess<'de>, 1453 | { 1454 | type Error = X::Error; 1455 | 1456 | fn next_element_seed(&mut self, seed: T) -> Result, X::Error> 1457 | where 1458 | T: DeserializeSeed<'de>, 1459 | { 1460 | let parent = self.chain; 1461 | let chain = Chain::Seq { 1462 | parent, 1463 | index: self.index, 1464 | }; 1465 | let track = self.track; 1466 | self.index += 1; 1467 | self.delegate 1468 | .next_element_seed(TrackedSeed::new(seed, chain, track)) 1469 | .map_err(|err| track.trigger(parent, err)) 1470 | } 1471 | 1472 | fn size_hint(&self) -> Option { 1473 | self.delegate.size_hint() 1474 | } 1475 | } 1476 | 1477 | // Map visitor that captures the string value of its keys and uses that to track 1478 | // the path to its values. 1479 | struct MapAccess<'a, 'b, X> { 1480 | delegate: X, 1481 | chain: &'a Chain<'a>, 1482 | key: Option, 1483 | track: &'b Track, 1484 | } 1485 | 1486 | impl<'a, 'b, X> MapAccess<'a, 'b, X> { 1487 | fn new(delegate: X, chain: &'a Chain<'a>, track: &'b Track) -> Self { 1488 | MapAccess { 1489 | delegate, 1490 | chain, 1491 | key: None, 1492 | track, 1493 | } 1494 | } 1495 | } 1496 | 1497 | impl<'a, 'b, 'de, X> de::MapAccess<'de> for MapAccess<'a, 'b, X> 1498 | where 1499 | X: de::MapAccess<'de>, 1500 | { 1501 | type Error = X::Error; 1502 | 1503 | fn next_key_seed(&mut self, seed: K) -> Result, X::Error> 1504 | where 1505 | K: DeserializeSeed<'de>, 1506 | { 1507 | let chain = self.chain; 1508 | let track = self.track; 1509 | let key = &mut self.key; 1510 | self.delegate 1511 | .next_key_seed(CaptureKey::new(seed, key)) 1512 | .map_err(|err| { 1513 | let chain = match key.take() { 1514 | Some(key) => Chain::Map { parent: chain, key }, 1515 | None => Chain::NonStringKey { parent: chain }, 1516 | }; 1517 | track.trigger(&chain, err) 1518 | }) 1519 | } 1520 | 1521 | fn next_value_seed(&mut self, seed: V) -> Result 1522 | where 1523 | V: DeserializeSeed<'de>, 1524 | { 1525 | let parent = self.chain; 1526 | let chain = match self.key.take() { 1527 | Some(key) => Chain::Map { parent, key }, 1528 | None => Chain::NonStringKey { parent }, 1529 | }; 1530 | let track = self.track; 1531 | self.delegate 1532 | .next_value_seed(TrackedSeed::new(seed, chain, track)) 1533 | .map_err(|err| track.trigger(parent, err)) 1534 | } 1535 | 1536 | fn size_hint(&self) -> Option { 1537 | self.delegate.size_hint() 1538 | } 1539 | } 1540 | --------------------------------------------------------------------------------