1use chumsky::input::ValueInput;
2use chumsky::prelude::SimpleSpan as Span;
3use chumsky::util::MaybeRef;
4use xee_xpath_lexer::Token;
5
6use crate::ast;
7
8#[derive(Debug, Clone, PartialEq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize))]
10pub enum ParserError {
11 ExpectedFound { span: Span },
12 UnknownPrefix { span: Span, prefix: String },
13 Reserved { span: Span, name: String },
14 ArityOverflow { span: Span },
15 UnknownType { span: Span, name: ast::Name },
16 IllegalFunctionInPattern { span: Span, name: ast::Name },
17}
18
19impl ParserError {
20 pub fn span(&self) -> Span {
21 match self {
22 Self::ExpectedFound { span, .. } => *span,
23 Self::UnknownPrefix { span, .. } => *span,
24 Self::Reserved { span, .. } => *span,
25 Self::ArityOverflow { span } => *span,
26 Self::UnknownType { span, .. } => *span,
27 Self::IllegalFunctionInPattern { span, .. } => *span,
28 }
29 }
30
31 pub fn adjust(mut self, start: usize) -> Self {
32 use ParserError::*;
33 let span = match &mut self {
34 ExpectedFound { span } => span,
35 UnknownPrefix { span, .. } => span,
36 Reserved { span, .. } => span,
37 ArityOverflow { span } => span,
38 UnknownType { span, .. } => span,
39 IllegalFunctionInPattern { span, .. } => span,
40 };
41 *span = Span::new(span.start + start, span.end + start);
42 self
43 }
44}
45
46impl<'a, I, L> chumsky::error::LabelError<'a, I, L> for ParserError
47where
48 I: ValueInput<'a, Token = Token<'a>, Span = Span>,
49{
50 fn expected_found<E: IntoIterator<Item = L>>(
57 _expected: E,
58 _found: Option<MaybeRef<'a, I::Token>>,
59 span: I::Span,
60 ) -> Self {
61 Self::ExpectedFound { span }
62 }
63}
64
65impl<'a, I> chumsky::error::Error<'a, I> for ParserError
66where
67 I: ValueInput<'a, Token = Token<'a>, Span = Span>,
68{
69 fn merge(self, other: Self) -> Self {
70 match (self, other) {
71 (
72 ParserError::ExpectedFound { span: span_a },
73 ParserError::ExpectedFound { span: _ },
74 ) => ParserError::ExpectedFound { span: span_a },
75 (ParserError::ExpectedFound { .. }, a) => a,
76 (a, ParserError::ExpectedFound { .. }) => a,
77 (a, _) => a,
78 }
79 }
80}