pochoir-lang 0.12.2

Custom parser and interpreter for the pochoir template engine
Documentation
use pochoir_common::Spanned;
use std::result;
use thiserror::Error;

pub type Result<T> = result::Result<T, Spanned<Error>>;

#[derive(Error, Debug, PartialEq, Eq, Clone)]
pub enum Error {
    #[error("mismatched types: expected {expected}, found {found}")]
    MismatchedTypes { expected: String, found: String },

    #[error("unknown operator {0:?}")]
    UnknownOperator(String),

    #[error("array cannot be indexed by {0}, the index must be a positive number or a range")]
    BadArrayIndex(String),

    #[error("object cannot be indexed by {0}, the index must be a string")]
    BadObjectIndex(String),

    #[error("string cannot be indexed by {0}, the index must be a positive number or a range")]
    BadStringIndex(String),

    #[error("range bound cannot be a {0}, the bound must be a positive number")]
    BadRangeBound(String),

    #[error("cannot index into a value of type {0}")]
    ValueCannotBeIndexed(String),

    #[error("an error happened when executing a function: {0}")]
    FunctionError(String),

    #[error("cannot call `null`")]
    CannotCallNull,

    #[error("cannot index `null`")]
    CannotIndexNull,

    #[error("invalid left-hand side of definition")]
    InvalidLeftHandDefinition,

    #[error("expected expression, found {0:?}")]
    ExpectedExpression(String),

    #[error("invalid number, it must be a 64-bit floating point number")]
    InvalidNumber,

    #[error("mismatched closing delimiter: {0:?}")]
    MismatchedClosingDelimiter(String),

    #[error("unterminated string")]
    UnterminatedString,

    #[error("unterminated array")]
    UnterminatedArray,

    #[error("unterminated object")]
    UnterminatedObject,

    #[error("expected bounded range")]
    ExpectedBoundedRange,

    #[error("expected range from")]
    ExpectedRangeFrom,

    #[error("expected range to")]
    ExpectedRangeTo,

    #[error("expected array of {expected} element(s) to be converted into a tuple, found {found} element(s)")]
    BadTupleLength { expected: usize, found: usize },

    #[error("missing field {0} in provided object")]
    MissingField(String),

    #[error("unknown enum variant {0}")]
    UnknownEnumVariant(String),

    #[error(transparent)]
    StreamParserError(#[from] pochoir_common::Error),
}

pub(crate) trait AutoErrorOffset<T>
where
    Self: Sized,
{
    fn auto_error_offset(self, file_offset: usize) -> T;
}

impl<T> AutoErrorOffset<result::Result<T, Spanned<Error>>>
    for result::Result<T, Spanned<pochoir_common::Error>>
{
    fn auto_error_offset(self, file_offset: usize) -> result::Result<T, Spanned<Error>> {
        self.map_err(|e| {
            let span = e.span().clone();
            e.map_spanned(Error::StreamParserError)
                .with_span(span.start + file_offset..span.end + file_offset)
        })
    }
}