1use crate::ascii::AsciiSet;
2use crate::parser::then::Then2;
3use crate::parser::{ParseState, Parser, ParserResult};
4use std::error::Error;
5use std::fmt::{Display, Formatter};
6
7#[non_exhaustive]
11#[derive(Debug, Copy, Clone)]
12pub enum ParseError {
13 Expected(&'static str),
15 ExpectedLiteral(&'static str),
17 ExpectedByte(u8),
19 ExpectedByteRange(u8, u8),
21 ExpectedOneOf(AsciiSet),
23 ExpectedAtLeastMatches(usize, fn(&u8) -> bool),
25 ExpectedAtMostMatches(usize, fn(&u8) -> bool),
27 ExpectedExactlyMatches(usize, fn(&u8) -> bool),
29 ExpectedLessItems(usize),
31 ExpectedEof(),
33 NumberTooLarge(i128),
35 NumberTooSmall(i128),
37 NumberOutOfRange(),
41 Custom(&'static str),
43}
44
45impl ParseError {
46 #[inline]
47 pub(super) fn too_large(max: impl TryInto<i128>) -> Self {
48 if let Ok(max) = max.try_into() {
49 Self::NumberTooLarge(max)
50 } else {
51 Self::NumberOutOfRange()
52 }
53 }
54
55 #[inline]
56 pub(super) fn too_small(min: impl TryInto<i128>) -> Self {
57 if let Ok(min) = min.try_into() {
58 Self::NumberTooSmall(min)
59 } else {
60 Self::NumberOutOfRange()
61 }
62 }
63}
64
65impl Display for ParseError {
66 #[cold]
67 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68 match *self {
69 ParseError::Expected(x) => write!(f, "expected {x}"),
70 ParseError::ExpectedLiteral(x) => write!(f, "expected {x:?}"),
71 ParseError::ExpectedByte(x) => write!(f, "expected {:?}", x as char),
72 ParseError::ExpectedByteRange(min, max) => {
73 write!(f, "expected {:?}-{:?}", min as char, max as char)
74 }
75 ParseError::ExpectedAtLeastMatches(n, set_fn) => {
76 let set = AsciiSet::from(|b| set_fn(&b));
77 if n == 1 {
78 write!(f, "expected at least 1 character matching {set}")
79 } else {
80 write!(f, "expected at least {n} characters matching {set}")
81 }
82 }
83 ParseError::ExpectedAtMostMatches(n, set_fn) => {
84 let set = AsciiSet::from(|b| set_fn(&b));
85 write!(f, "expected at most {n} characters matching {set}")
86 }
87 ParseError::ExpectedExactlyMatches(n, set_fn) => {
88 let set = AsciiSet::from(|b| set_fn(&b));
89 write!(f, "expected exactly {n} characters matching {set}")
90 }
91 ParseError::ExpectedOneOf(set) => write!(f, "expected one of {set}"),
92 ParseError::ExpectedEof() => write!(f, "expected end of input"),
93 ParseError::ExpectedLessItems(x) => write!(f, "expected {x} items or less"),
94 ParseError::NumberTooLarge(x) => write!(f, "expected number <= {x}"),
95 ParseError::NumberTooSmall(x) => write!(f, "expected number >= {x}"),
96 ParseError::NumberOutOfRange() => write!(f, "number out of range"),
97 ParseError::Custom(x) => f.write_str(x),
98 }
99 }
100}
101
102impl Error for ParseError {}
103
104impl PartialEq for ParseError {
105 fn eq(&self, other: &Self) -> bool {
106 match (*self, *other) {
107 (Self::ExpectedAtLeastMatches(a1, a2), Self::ExpectedAtLeastMatches(b1, b2))
113 | (Self::ExpectedAtMostMatches(a1, a2), Self::ExpectedAtMostMatches(b1, b2))
114 | (Self::ExpectedExactlyMatches(a1, a2), Self::ExpectedExactlyMatches(b1, b2)) => {
115 a1 == b1 && AsciiSet::from(|b| a2(&b)) == AsciiSet::from(|b| b2(&b))
116 }
117
118 (Self::Expected(a), Self::Expected(b))
120 | (Self::ExpectedLiteral(a), Self::ExpectedLiteral(b))
121 | (Self::Custom(a), Self::Custom(b)) => a == b,
122 (Self::ExpectedByte(a), Self::ExpectedByte(b)) => a == b,
123 (Self::ExpectedByteRange(a1, a2), Self::ExpectedByteRange(b1, b2)) => {
124 a1 == b1 && a2 == b2
125 }
126 (Self::ExpectedOneOf(a), Self::ExpectedOneOf(b)) => a == b,
127 (Self::ExpectedLessItems(a), Self::ExpectedLessItems(b)) => a == b,
128 (Self::ExpectedEof(), Self::ExpectedEof())
129 | (Self::NumberOutOfRange(), Self::NumberOutOfRange()) => true,
130 (Self::NumberTooLarge(a), Self::NumberTooLarge(b))
131 | (Self::NumberTooSmall(a), Self::NumberTooSmall(b)) => a == b,
132
133 (
135 Self::Expected(_)
136 | Self::ExpectedLiteral(_)
137 | Self::ExpectedByte(_)
138 | Self::ExpectedByteRange(_, _)
139 | Self::ExpectedOneOf(_)
140 | Self::ExpectedAtLeastMatches(_, _)
141 | Self::ExpectedAtMostMatches(_, _)
142 | Self::ExpectedExactlyMatches(_, _)
143 | Self::ExpectedLessItems(_)
144 | Self::ExpectedEof()
145 | Self::NumberTooLarge(_)
146 | Self::NumberTooSmall(_)
147 | Self::NumberOutOfRange()
148 | Self::Custom(_),
149 _,
150 ) => false,
151 }
152 }
153}
154
155impl Eq for ParseError {}
156
157impl PartialEq<ParseError> for Box<dyn Error> {
158 fn eq(&self, other: &ParseError) -> bool {
159 if let Some(pe) = self.downcast_ref::<ParseError>() {
160 pe == other
161 } else {
162 false
163 }
164 }
165}
166impl PartialEq<Box<dyn Error>> for ParseError {
167 fn eq(&self, other: &Box<dyn Error>) -> bool {
168 other == self
169 }
170}
171
172#[derive(Copy, Clone)]
173pub struct WithErrorMsg<P> {
174 pub(super) parser: P,
175 pub(super) message: &'static str,
176}
177impl<'i, P: Parser<'i>> Parser<'i> for WithErrorMsg<P> {
178 type Output = P::Output;
179 type Then<T: Parser<'i>> = Then2<Self, T>;
180
181 #[inline]
182 fn parse_ctx(
183 &self,
184 input: &'i [u8],
185 state: &mut ParseState<'i>,
186 commit: &mut bool,
187 tail: bool,
188 ) -> ParserResult<'i, Self::Output> {
189 let prev_remaining = state.error.map(|e| e.1);
190 self.parser
191 .parse_ctx(input, state, commit, tail)
192 .inspect_err(|_| {
193 let remaining = state.error.unwrap().1;
194 if prev_remaining != Some(remaining) {
195 state.error = Some((ParseError::Custom(self.message), remaining));
197 }
198 })
199 }
200}