winnow_parse_error/
lib.rs1use std::{error::Error, fmt::Display};
2use winnow::error::ContextError;
3
4#[derive(Debug, PartialEq, Eq)]
5pub struct ParseError {
6 message: String,
7 span: std::ops::Range<usize>,
8 input: String,
9}
10
11impl ParseError {
12 pub fn from_parse(error: winnow::error::ParseError<&str, ContextError>) -> Self {
14 let message = error.inner().to_string();
15 let input = (*error.input()).to_owned();
16 let span = error.char_span();
17 Self {
18 message,
19 span,
20 input,
21 }
22 }
23}
24
25impl Display for ParseError {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 let message = annotate_snippets::Level::Error
28 .title(&self.message)
29 .snippet(
30 annotate_snippets::Snippet::source(&self.input)
31 .fold(true)
32 .annotation(annotate_snippets::Level::Error.span(self.span.clone())),
33 );
34 let renderer = annotate_snippets::Renderer::plain();
35 let rendered = renderer.render(message);
36 rendered.fmt(f)
37 }
38}
39
40impl Error for ParseError {}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use pretty_assertions::assert_eq;
46
47 }