use std::{error::Error, fmt::Display};
use crate::spans::Span;
use thiserror::Error;
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Error, Clone, Hash, Copy)]
pub struct SpannedError<E> {
pub error: E,
pub span: Span,
}
impl<E> SpannedError<E> {
pub fn new(error: E, span: impl Into<Span>) -> Self {
SpannedError {
error,
span: span.into(),
}
}
}
impl<V> SpannedError<V> {
pub fn convert<U>(value: SpannedError<U>) -> Self
where
V: From<U>,
{
Self {
error: value.error.into(),
span: value.span,
}
}
}
#[allow(dead_code)]
trait WithSpan {
type Output;
type Error;
fn with_span(self, span: Span) -> Result<Self::Output, SpannedError<Self::Error>>;
}
impl<T, E: Error> WithSpan for Result<T, E> {
type Output = T;
type Error = E;
fn with_span(self, span: Span) -> Result<Self::Output, SpannedError<Self::Error>> {
match self {
Ok(x) => Ok(x),
Err(error) => Err(SpannedError { error, span }),
}
}
}
impl<E> Display for SpannedError<E>
where
E: Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.error)
}
}