toml_parser/
error.rs

1use crate::Span;
2
3pub trait ErrorSink {
4    fn report_error(&mut self, error: ParseError);
5}
6
7impl<F> ErrorSink for F
8where
9    F: FnMut(ParseError),
10{
11    fn report_error(&mut self, error: ParseError) {
12        (self)(error);
13    }
14}
15
16impl ErrorSink for () {
17    fn report_error(&mut self, _error: ParseError) {}
18}
19
20impl ErrorSink for Option<ParseError> {
21    fn report_error(&mut self, error: ParseError) {
22        self.get_or_insert(error);
23    }
24}
25
26#[cfg(feature = "alloc")]
27#[allow(unused_qualifications)]
28impl ErrorSink for alloc::vec::Vec<ParseError> {
29    fn report_error(&mut self, error: ParseError) {
30        self.push(error);
31    }
32}
33
34#[derive(Clone, PartialEq, Eq, Debug)]
35#[non_exhaustive]
36pub struct ParseError {
37    context: Option<Span>,
38    description: ErrorStr,
39    expected: Option<&'static [Expected]>,
40    unexpected: Option<Span>,
41}
42
43impl ParseError {
44    pub fn new(description: impl Into<ErrorStr>) -> Self {
45        Self {
46            context: None,
47            description: description.into(),
48            expected: None,
49            unexpected: None,
50        }
51    }
52
53    pub fn with_context(mut self, context: Span) -> Self {
54        self.context = Some(context);
55        self
56    }
57
58    pub fn with_expected(mut self, expected: &'static [Expected]) -> Self {
59        self.expected = Some(expected);
60        self
61    }
62
63    pub fn with_unexpected(mut self, unexpected: Span) -> Self {
64        self.unexpected = Some(unexpected);
65        self
66    }
67
68    pub fn context(&self) -> Option<Span> {
69        self.context
70    }
71    pub fn description(&self) -> &str {
72        &self.description
73    }
74    pub fn expected(&self) -> Option<&'static [Expected]> {
75        self.expected
76    }
77    pub fn unexpected(&self) -> Option<Span> {
78        self.unexpected
79    }
80
81    pub(crate) fn rebase_spans(mut self, offset: usize) -> Self {
82        if let Some(context) = self.context.as_mut() {
83            *context += offset;
84        }
85        if let Some(unexpected) = self.unexpected.as_mut() {
86            *unexpected += offset;
87        }
88        self
89    }
90}
91
92#[cfg(feature = "alloc")]
93type ErrorStr = alloc::borrow::Cow<'static, str>;
94#[cfg(not(feature = "alloc"))]
95type ErrorStr = &'static str;
96
97#[derive(Copy, Clone, PartialEq, Eq, Debug)]
98#[non_exhaustive]
99pub enum Expected {
100    Literal(&'static str),
101    Description(&'static str),
102}