hq_rs/filter/
error.rs

1use core::fmt;
2
3use annotate_snippets::{Level, Renderer, Snippet};
4use pest::{error::InputLocation, RuleType};
5
6pub struct FilterError<R> {
7    parsing_error: pest::error::Error<R>,
8}
9
10impl<R> fmt::Debug for FilterError<R>
11where
12    R: RuleType,
13{
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        let input = self.parsing_error.line();
16        let pos = match self.parsing_error.location {
17            InputLocation::Pos(pos) => pos..pos,
18            InputLocation::Span((start, end)) => start..end,
19        };
20
21        let message = Level::Error.title("failed to parse filter").snippet(
22            Snippet::source(input).annotation(Level::Error.span(pos).label("unexpected token")),
23        );
24
25        let renderer = Renderer::styled();
26        let rendered = renderer.render(message);
27
28        write!(f, "{}", rendered)
29    }
30}
31
32impl<R> fmt::Display for FilterError<R>
33where
34    R: RuleType,
35{
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        write!(f, "{:?}", self)
38    }
39}
40
41impl<R> std::error::Error for FilterError<R> where R: RuleType {}
42
43impl<R> From<pest::error::Error<R>> for Box<FilterError<R>>
44where
45    R: RuleType,
46{
47    fn from(value: pest::error::Error<R>) -> Self {
48        match value.variant {
49            pest::error::ErrorVariant::ParsingError {
50                positives: _,
51                negatives: _,
52            } => Box::new(FilterError {
53                parsing_error: value.clone(),
54            }),
55            _ => {
56                unimplemented!()
57            }
58        }
59    }
60}