toml_edit/parser/
error.rs

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 `{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}