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