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}