femstache 0.1.5

Embrace the feminine mustache to unlock your templating dreams! Or something, I don't know. :3
Documentation
use core::fmt;
use std::error::Error as StdError;

use femstache_loader::LoaderError;
use femstache_parser::nodes::Ident;
use femstache_types::error::TyError;

pub use femstache_parser::{ParseError, ParseResult};

#[derive(Debug)]
pub enum EvalError {
    // TODO: attach span
    InvalidType,
    NoMember(Ident),
    NoDictKey(String),
    VariableNotFound(Ident),
    Loader(LoaderError),
}

impl StdError for EvalError {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match self {
            EvalError::Loader(inner) => Some(inner),
            _ => None,
        }
    }
}

impl fmt::Display for EvalError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            EvalError::InvalidType => write!(f, "invalid type"),
            EvalError::NoMember(ident) => write!(f, "struct does not have member {ident:?}"),
            EvalError::NoDictKey(key) => write!(f, "dict does not have key {key:?}"),
            EvalError::VariableNotFound(ident) => write!(f, "variable {} not found", ident.data),
            EvalError::Loader(inner) => write!(f, "loader error: {inner}"),
        }
    }
}

impl From<LoaderError> for EvalError {
    fn from(err: LoaderError) -> Self {
        Self::Loader(err)
    }
}

pub type EvalResult<T> = Result<T, EvalError>;

#[derive(Debug)]
pub enum FemstacheError {
    EvalError(EvalError),
    TypeError(TyError),
    LoaderError(LoaderError),
}

impl StdError for FemstacheError {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match self {
            FemstacheError::EvalError(eval_error) => Some(eval_error),
            FemstacheError::TypeError(ty_error) => Some(ty_error),
            FemstacheError::LoaderError(loader_error) => Some(loader_error),
        }
    }
}

impl fmt::Display for FemstacheError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FemstacheError::EvalError(eval_error) => {
                write!(f, "eval error: {}", eval_error)
            }
            FemstacheError::TypeError(ty_error) => {
                write!(f, "type error: {}", ty_error)
            }
            FemstacheError::LoaderError(loader_error) => {
                write!(f, "loader error: {}", loader_error)
            }
        }
    }
}

impl From<EvalError> for FemstacheError {
    fn from(err: EvalError) -> Self {
        FemstacheError::EvalError(err)
    }
}

impl From<TyError> for FemstacheError {
    fn from(err: TyError) -> Self {
        FemstacheError::TypeError(err)
    }
}

impl From<LoaderError> for FemstacheError {
    fn from(err: LoaderError) -> Self {
        FemstacheError::LoaderError(err)
    }
}

pub type FemstacheResult<T> = Result<T, FemstacheError>;