| 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 ` {key}` in document root" ) |
| 67 | } else { |
| 68 | let path = table.iter().map(|k| k.get()).collect::<Vec<_>>().join("." ); |
| 69 | write!(f, "duplicate key ` {key}` in table ` {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 ` {path}` attempted to extend non-table type ( {actual})" |
| 80 | ) |
| 81 | } |
| 82 | CustomError::OutOfRange => write!(f, "value is out of range" ), |
| 83 | CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceeded" ), |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | |