smt_scope/formatter/
error.rs

1use crate::NonMaxU32;
2
3use super::{ConstSplit, Formatter, Matcher};
4
5#[derive(Debug, Clone)]
6pub enum TdcError {
7    DuplicateExactMatcher(String, Option<NonMaxU32>),
8}
9
10#[derive(Debug, Clone)]
11pub enum FallbackParseError {
12    MaxCaptureTooLarge(NonMaxU32),
13    FormatterParseError(FormatterParseError),
14}
15
16#[derive(Debug)]
17pub enum ConversionError {
18    Regex(regex::Error),
19    FormatterExpectsRegex(Matcher, Formatter),
20    RegexNotEnoughCaptures(Matcher, Formatter),
21    MatcherError(MatcherParseError),
22    FormatterParseError(FormatterParseError),
23}
24
25impl From<regex::Error> for ConversionError {
26    fn from(err: regex::Error) -> Self {
27        Self::Regex(err)
28    }
29}
30
31impl From<MatcherParseError> for ConversionError {
32    fn from(err: MatcherParseError) -> Self {
33        Self::MatcherError(err)
34    }
35}
36
37impl From<FormatterParseError> for ConversionError {
38    fn from(err: FormatterParseError) -> Self {
39        Self::FormatterParseError(err)
40    }
41}
42
43pub type FormatterParseError = ParseError<FormatterError>;
44pub type MatcherParseError = ParseError<MatcherError>;
45
46#[derive(Debug, Clone)]
47pub struct ParseError<T> {
48    pub s: String,
49    pub kind: T,
50}
51
52impl<T> From<ParseErrorConst<'_, T>> for ParseError<T> {
53    fn from(err: ParseErrorConst<'_, T>) -> Self {
54        Self {
55            s: err.s.to_owned(),
56            kind: err.kind,
57        }
58    }
59}
60
61pub type ResultFormatterConst<'a, T> = Result<T, ParseErrorConst<'a, FormatterError>>;
62pub type ResultMatcherConst<'a, T> = Result<T, ParseErrorConst<'a, MatcherError>>;
63pub type ResultConst<'a, T> = Result<T, ParseErrorConst<'a, EitherError>>;
64
65#[derive(Debug)]
66pub struct ParseErrorConst<'a, T> {
67    pub s: &'a str,
68    pub kind: T,
69}
70
71#[derive(Debug, Clone)]
72pub enum FormatterError {
73    MissingHash,
74    MissingRange,
75    MissingControl(&'static str),
76    TooManyControl(char),
77    TooManyChildren,
78    UnexpectedPair,
79    IncorrectControl,
80    InvalidNumber,
81    CaptureOverflow,
82}
83
84impl FormatterError {
85    #[allow(clippy::no_effect)]
86    pub const fn const_error<T>(&self, error: bool) -> T {
87        use FormatterError::*;
88        match self {
89            MissingHash => [()][error as usize],
90            MissingRange => [()][error as usize],
91            MissingControl(_) => [()][error as usize],
92            TooManyControl(_) => [()][error as usize],
93            TooManyChildren => [()][error as usize],
94            UnexpectedPair => [()][error as usize],
95            IncorrectControl => [()][error as usize],
96            InvalidNumber => [()][error as usize],
97            CaptureOverflow => [()][error as usize],
98        };
99        loop {
100            [()][!error as usize];
101        }
102    }
103}
104
105impl<'a> ParseErrorConst<'a, FormatterError> {
106    pub(super) const fn missing_hash(s: &'a str) -> Self {
107        Self {
108            s,
109            kind: FormatterError::MissingHash,
110        }
111    }
112    pub(super) const fn invalid_number(s: &'a str) -> Self {
113        Self {
114            s,
115            kind: FormatterError::InvalidNumber,
116        }
117    }
118    pub(super) const fn missing_range(s: &'a str) -> Self {
119        Self {
120            s,
121            kind: FormatterError::MissingRange,
122        }
123    }
124    pub(super) const fn missing_control(s: &'a str, expected: &'static str) -> Self {
125        Self {
126            s,
127            kind: FormatterError::MissingControl(expected),
128        }
129    }
130    pub(super) const fn too_many_control(split: ConstSplit<'a, 1>) -> Self {
131        Self {
132            s: split.remainder(),
133            kind: FormatterError::TooManyControl(split.control()),
134        }
135    }
136    pub(super) const fn too_many_children(s: &'a str) -> Self {
137        Self {
138            s,
139            kind: FormatterError::TooManyChildren,
140        }
141    }
142    pub(super) const fn unexpected_pair(s: &'a str) -> Self {
143        Self {
144            s,
145            kind: FormatterError::UnexpectedPair,
146        }
147    }
148    pub(super) const fn incorrect_control(s: &'a str) -> Self {
149        Self {
150            s,
151            kind: FormatterError::IncorrectControl,
152        }
153    }
154    pub(super) const fn capture_overflow(s: &'a str) -> Self {
155        Self {
156            s,
157            kind: FormatterError::CaptureOverflow,
158        }
159    }
160}
161
162#[derive(Debug, Clone)]
163pub enum MatcherError {
164    InvalidChildrenSpec,
165}
166
167impl MatcherError {
168    #[allow(clippy::no_effect)]
169    pub const fn const_error<T>(&self, error: bool) -> T {
170        use MatcherError::*;
171        match self {
172            InvalidChildrenSpec => [()][error as usize],
173        };
174        loop {
175            [()][!error as usize];
176        }
177    }
178}
179
180impl<'a> ParseErrorConst<'a, MatcherError> {
181    pub(super) const fn invalid_children_spec(s: &'a str) -> Self {
182        Self {
183            s,
184            kind: MatcherError::InvalidChildrenSpec,
185        }
186    }
187}
188
189pub enum EitherError {
190    Formatter(FormatterError),
191    Matcher(MatcherError),
192    InvalidCapture,
193}
194
195impl EitherError {
196    #[allow(clippy::no_effect)]
197    pub const fn const_error<T>(&self, error: bool) -> T {
198        use EitherError::*;
199        match self {
200            Formatter(err) => err.const_error(error),
201            Matcher(err) => err.const_error(error),
202            InvalidCapture => [()][error as usize],
203        };
204        loop {
205            [()][!error as usize];
206        }
207    }
208}
209
210impl<'a> ParseErrorConst<'a, EitherError> {
211    pub(super) const fn formatter(err: ParseErrorConst<'a, FormatterError>) -> Self {
212        Self {
213            s: err.s,
214            kind: EitherError::Formatter(err.kind),
215        }
216    }
217    pub(super) const fn matcher(err: ParseErrorConst<'a, MatcherError>) -> Self {
218        Self {
219            s: err.s,
220            kind: EitherError::Matcher(err.kind),
221        }
222    }
223
224    pub(super) const fn invalid_capture(s: &'a str) -> Self {
225        Self {
226            s,
227            kind: EitherError::InvalidCapture,
228        }
229    }
230}