1use std::error::Error as StdError;
2use std::fmt::{Display, Formatter, Result};
3
4use crate::Key;
5
6#[derive(Debug, Clone)]
7pub(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
21impl 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
54impl StdError for CustomError {
55 fn description(&self) -> &'static str {
56 "TOML parse error"
57 }
58}
59
60impl 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