1use pest::Span;
2use std::fmt::{Display, Formatter};
3
4#[derive(Clone, Debug, PartialEq, Eq, Hash)]
11pub struct ParseError {
12 pub(crate) inner: InnerParseError,
13}
14
15impl ParseError {
16 pub(crate) fn new(inner: InnerParseError) -> Self {
20 Self { inner }
21 }
22}
23
24impl Display for ParseError {
25 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26 Display::fmt(&self.inner, f)
27 }
28}
29
30impl std::error::Error for ParseError {
31 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
35 self.inner.source()
36 }
37}
38
39#[derive(Clone, Debug, PartialEq, Eq, Hash)]
40pub(crate) enum InnerParseError {
41 Pest(crate::query::Error),
42 Other(DetachedSpan, String),
43}
44
45impl Display for InnerParseError {
46 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
47 match &self {
48 InnerParseError::Pest(error) => Display::fmt(error, f),
49 InnerParseError::Other(_, message) => Display::fmt(message, f),
50 }
51 }
52}
53
54impl std::error::Error for InnerParseError {
55 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
56 match self {
57 InnerParseError::Pest(err) => Some(err),
58 InnerParseError::Other(_, _) => None,
59 }
60 }
61}
62
63impl ParseError {
64 pub fn to_string(&self, query_text: &str) -> String {
79 match &self.inner {
80 InnerParseError::Pest(e) => format!("{e}"),
81 InnerParseError::Other(span, message) => match Span::new(query_text, span.start, span.end) {
82 None => message.to_string(),
83 Some(span) => {
84 let pest_err = crate::query::Error::new_from_span(span, message.to_string());
85 pest_err.to_string()
86 }
87 },
88 }
89 }
90}
91
92impl From<crate::query::Error> for InnerParseError {
93 fn from(err: crate::query::Error) -> Self {
94 Self::Pest(err)
95 }
96}
97
98#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Hash)]
100pub struct DetachedSpan {
101 pub start: usize,
102 pub end: usize,
103}
104
105impl From<pest::Span<'_>> for DetachedSpan {
106 fn from(value: pest::Span) -> Self {
107 Self {
108 start: value.start(),
109 end: value.end(),
110 }
111 }
112}
113
114impl From<&crate::query::Pair<'_>> for DetachedSpan {
115 fn from(value: &crate::query::Pair<'_>) -> Self {
116 value.as_span().into()
117 }
118}