1use crate::parser::then::Then2;
2use crate::parser::{ParseResult, Parser};
3use std::error::Error;
4use std::fmt::{Display, Formatter};
5
6#[non_exhaustive]
8#[derive(Debug, Copy, Clone, PartialEq, Eq)]
9pub enum ParseError {
10 Expected(&'static str),
12 ExpectedLiteral(&'static str),
14 ExpectedByte(u8),
16 ExpectedByteRange(u8, u8),
18 ExpectedMatches(usize),
20 ExpectedLessItems(usize),
22 ExpectedEof(),
24 NumberTooLarge(i128),
26 NumberTooSmall(i128),
28 NumberOutOfRange(),
32 Custom(&'static str),
34}
35
36impl ParseError {
37 #[inline]
38 pub(super) fn too_large(max: impl TryInto<i128>) -> Self {
39 if let Ok(max) = max.try_into() {
40 Self::NumberTooLarge(max)
41 } else {
42 Self::NumberOutOfRange()
43 }
44 }
45
46 #[inline]
47 pub(super) fn too_small(min: impl TryInto<i128>) -> Self {
48 if let Ok(min) = min.try_into() {
49 Self::NumberTooSmall(min)
50 } else {
51 Self::NumberOutOfRange()
52 }
53 }
54}
55
56impl Display for ParseError {
57 #[cold]
58 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
59 match *self {
60 ParseError::Expected(x) => write!(f, "expected {x}"),
61 ParseError::ExpectedLiteral(x) => write!(f, "expected {x:?}"),
62 ParseError::ExpectedByte(x) => write!(f, "expected {:?}", x.escape_ascii().to_string()),
63 ParseError::ExpectedByteRange(min, max) => {
64 write!(
65 f,
66 "expected {:?}-{:?}",
67 min.escape_ascii().to_string(),
68 max.escape_ascii().to_string(),
69 )
70 }
71 ParseError::ExpectedEof() => write!(f, "expected end of input"),
72 ParseError::ExpectedMatches(x) => write!(f, "expected at least {x} match"),
73 ParseError::ExpectedLessItems(x) => write!(f, "expected {x} items or less"),
74 ParseError::NumberTooLarge(x) => write!(f, "expected number <= {x}"),
75 ParseError::NumberTooSmall(x) => write!(f, "expected number >= {x}"),
76 ParseError::NumberOutOfRange() => write!(f, "number out of range"),
77 ParseError::Custom(x) => f.write_str(x),
78 }
79 }
80}
81
82impl Error for ParseError {}
83
84#[derive(Copy, Clone)]
85pub struct WithErrorMsg<P> {
86 pub(super) parser: P,
87 pub(super) message: &'static str,
88}
89impl<'i, P: Parser<'i>> Parser<'i> for WithErrorMsg<P> {
90 type Output = P::Output;
91 type Then<T: Parser<'i>> = Then2<Self, T>;
92
93 #[inline]
94 fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
95 match self.parser.parse(input) {
96 Ok(v) => Ok(v),
97 Err((_, pos)) => Err((ParseError::Custom(self.message), pos)),
98 }
99 }
100}