1 use winnow::error::AddContext;
2 use winnow::error::ErrMode;
3 use winnow::error::ErrorKind;
4 use winnow::error::FromExternalError;
5 use winnow::error::ParserError;
6 use winnow::prelude::*;
7 use winnow::stream::Stream;
8
9 #[derive(Debug)]
10 pub enum CustomError<I> {
11 MyError,
12 Winnow(I, ErrorKind),
13 External {
14 cause: Box<dyn std::error::Error + Send + Sync + 'static>,
15 input: I,
16 kind: ErrorKind,
17 },
18 }
19
20 impl<I: Stream + Clone> ParserError<I> for CustomError<I> {
from_error_kind(input: &I, kind: ErrorKind) -> Self21 fn from_error_kind(input: &I, kind: ErrorKind) -> Self {
22 CustomError::Winnow(input.clone(), kind)
23 }
24
append(self, _: &I, _: &<I as Stream>::Checkpoint, _: ErrorKind) -> Self25 fn append(self, _: &I, _: &<I as Stream>::Checkpoint, _: ErrorKind) -> Self {
26 self
27 }
28 }
29
30 impl<C, I: Stream> AddContext<I, C> for CustomError<I> {
31 #[inline]
add_context( self, _input: &I, _token_start: &<I as Stream>::Checkpoint, _context: C, ) -> Self32 fn add_context(
33 self,
34 _input: &I,
35 _token_start: &<I as Stream>::Checkpoint,
36 _context: C,
37 ) -> Self {
38 self
39 }
40 }
41
42 impl<I: Stream + Clone, E: std::error::Error + Send + Sync + 'static> FromExternalError<I, E>
43 for CustomError<I>
44 {
45 #[inline]
from_external_error(input: &I, kind: ErrorKind, e: E) -> Self46 fn from_external_error(input: &I, kind: ErrorKind, e: E) -> Self {
47 CustomError::External {
48 cause: Box::new(e),
49 input: input.clone(),
50 kind,
51 }
52 }
53 }
54
parse<'s>(_input: &mut &'s str) -> PResult<&'s str, CustomError<&'s str>>55 pub fn parse<'s>(_input: &mut &'s str) -> PResult<&'s str, CustomError<&'s str>> {
56 Err(ErrMode::Backtrack(CustomError::MyError))
57 }
58
main()59 fn main() {}
60
61 #[cfg(test)]
62 mod tests {
63 use super::*;
64
65 #[test]
it_works()66 fn it_works() {
67 let err = parse.parse_next(&mut "").unwrap_err();
68 assert!(matches!(err, ErrMode::Backtrack(CustomError::MyError)));
69 }
70 }
71