1 | use std::error::Error as StdError; |
2 | use std::fmt::{Display, Formatter, Result}; |
3 | |
4 | use crate::Key; |
5 | |
6 | #[derive (Debug, Clone)] |
7 | pub(crate) enum CustomError { |
8 | DuplicateKey { |
9 | key: String, |
10 | table: Option<Vec<Key>>, |
11 | }, |
12 | DottedKeyExtendWrongType { |
13 | key: Vec<Key>, |
14 | actual: &'static str, |
15 | }, |
16 | OutOfRange, |
17 | #[cfg_attr (feature = "unbounded" , allow(dead_code))] |
18 | RecursionLimitExceeded, |
19 | } |
20 | |
21 | impl CustomError { |
22 | pub(crate) fn duplicate_key(path: &[Key], i: usize) -> Self { |
23 | assert!(i < path.len()); |
24 | let key = &path[i]; |
25 | let repr = key |
26 | .as_repr() |
27 | .and_then(|key| key.as_raw().as_str()) |
28 | .map(|s| s.to_owned()) |
29 | .unwrap_or_else(|| { |
30 | #[cfg (feature = "display" )] |
31 | { |
32 | key.default_repr().as_raw().as_str().unwrap().to_owned() |
33 | } |
34 | #[cfg (not(feature = "display" ))] |
35 | { |
36 | format!(" {:?}" , key.get()) |
37 | } |
38 | }); |
39 | Self::DuplicateKey { |
40 | key: repr, |
41 | table: Some(path[..i].to_vec()), |
42 | } |
43 | } |
44 | |
45 | pub(crate) fn extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> Self { |
46 | assert!(i < path.len()); |
47 | Self::DottedKeyExtendWrongType { |
48 | key: path[..=i].to_vec(), |
49 | actual, |
50 | } |
51 | } |
52 | } |
53 | |
54 | impl StdError for CustomError { |
55 | fn description(&self) -> &'static str { |
56 | "TOML parse error" |
57 | } |
58 | } |
59 | |
60 | impl Display for CustomError { |
61 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { |
62 | match self { |
63 | CustomError::DuplicateKey { key, table } => { |
64 | if let Some(table) = table { |
65 | if table.is_empty() { |
66 | write!(f, "duplicate key ` {}` in document root" , key) |
67 | } else { |
68 | let path = table.iter().map(|k| k.get()).collect::<Vec<_>>().join("." ); |
69 | write!(f, "duplicate key ` {}` in table ` {}`" , key, path) |
70 | } |
71 | } else { |
72 | write!(f, "duplicate key ` {}`" , key) |
73 | } |
74 | } |
75 | CustomError::DottedKeyExtendWrongType { key, actual } => { |
76 | let path = key.iter().map(|k| k.get()).collect::<Vec<_>>().join("." ); |
77 | write!( |
78 | f, |
79 | "dotted key ` {}` attempted to extend non-table type ( {})" , |
80 | path, actual |
81 | ) |
82 | } |
83 | CustomError::OutOfRange => write!(f, "value is out of range" ), |
84 | CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceeded" ), |
85 | } |
86 | } |
87 | } |
88 | |