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