| use std::error::Error as StdError; |
| use std::fmt::{Display, Formatter, Result}; |
| |
| use crate::Key; |
| |
| #[derive(Debug, Clone)] |
| pub(crate) enum CustomError { |
| DuplicateKey { |
| key: String, |
| table: Option<Vec<Key>>, |
| }, |
| DottedKeyExtendWrongType { |
| key: Vec<Key>, |
| actual: &'static str, |
| }, |
| OutOfRange, |
| #[cfg_attr(feature = "unbounded", allow(dead_code))] |
| RecursionLimitExceeded, |
| } |
| |
| impl CustomError { |
| pub(crate) fn duplicate_key(path: &[Key], i: usize) -> Self { |
| assert!(i < path.len()); |
| let key = &path[i]; |
| let repr = key |
| .as_repr() |
| .and_then(|key| key.as_raw().as_str()) |
| .map(|s| s.to_owned()) |
| .unwrap_or_else(|| { |
| #[cfg(feature = "display")] |
| { |
| key.default_repr().as_raw().as_str().unwrap().to_owned() |
| } |
| #[cfg(not(feature = "display"))] |
| { |
| format!("{:?}", key.get()) |
| } |
| }); |
| Self::DuplicateKey { |
| key: repr, |
| table: Some(path[..i].to_vec()), |
| } |
| } |
| |
| pub(crate) fn extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> Self { |
| assert!(i < path.len()); |
| Self::DottedKeyExtendWrongType { |
| key: path[..=i].to_vec(), |
| actual, |
| } |
| } |
| } |
| |
| impl StdError for CustomError { |
| fn description(&self) -> &'static str { |
| "TOML parse error" |
| } |
| } |
| |
| impl Display for CustomError { |
| fn fmt(&self, f: &mut Formatter<'_>) -> Result { |
| match self { |
| CustomError::DuplicateKey { key, table } => { |
| if let Some(table) = table { |
| if table.is_empty() { |
| write!(f, "duplicate key `{}` in document root", key) |
| } else { |
| let path = table.iter().map(|k| k.get()).collect::<Vec<_>>().join("."); |
| write!(f, "duplicate key `{}` in table `{}`", key, path) |
| } |
| } else { |
| write!(f, "duplicate key `{}`", key) |
| } |
| } |
| CustomError::DottedKeyExtendWrongType { key, actual } => { |
| let path = key.iter().map(|k| k.get()).collect::<Vec<_>>().join("."); |
| write!( |
| f, |
| "dotted key `{}` attempted to extend non-table type ({})", |
| path, actual |
| ) |
| } |
| CustomError::OutOfRange => write!(f, "value is out of range"), |
| CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceeded"), |
| } |
| } |
| } |