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 { duplicate_key(path: &[Key], i: usize) -> Self22 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 extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> Self45 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 { description(&self) -> &'static str55 fn description(&self) -> &'static str { 56 "TOML parse error" 57 } 58 } 59 60 impl Display for CustomError { fmt(&self, f: &mut Formatter<'_>) -> Result61 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