• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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