use pest::Span;
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ParseError {
pub(crate) inner: InnerParseError,
}
impl ParseError {
pub(crate) fn new(inner: InnerParseError) -> Self {
Self { inner }
}
}
impl Display for ParseError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self.inner, f)
}
}
impl std::error::Error for ParseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.inner.source()
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub(crate) enum InnerParseError {
Pest(crate::query::Error),
Other(DetachedSpan, String),
}
impl Display for InnerParseError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match &self {
InnerParseError::Pest(error) => Display::fmt(error, f),
InnerParseError::Other(_, message) => Display::fmt(message, f),
}
}
}
impl std::error::Error for InnerParseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
InnerParseError::Pest(err) => Some(err),
InnerParseError::Other(_, _) => None,
}
}
}
impl ParseError {
pub fn to_string(&self, query_text: &str) -> String {
match &self.inner {
InnerParseError::Pest(e) => format!("{e}"),
InnerParseError::Other(span, message) => match Span::new(query_text, span.start, span.end) {
None => message.to_string(),
Some(span) => {
let pest_err = crate::query::Error::new_from_span(span, message.to_string());
pest_err.to_string()
}
},
}
}
}
impl From<crate::query::Error> for InnerParseError {
fn from(err: crate::query::Error) -> Self {
Self::Pest(err)
}
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Hash)]
pub(crate) struct DetachedSpan {
pub(crate) start: usize,
pub(crate) end: usize,
}
impl From<pest::Span<'_>> for DetachedSpan {
fn from(value: pest::Span) -> Self {
Self {
start: value.start(),
end: value.end(),
}
}
}
impl From<&crate::query::Pair<'_>> for DetachedSpan {
fn from(value: &crate::query::Pair<'_>) -> Self {
value.as_span().into()
}
}