use alloc::format;
use alloc::string::String;
use thiserror::Error;
fn fmt_src_err(name: &Option<String>, line: usize, col: usize, message: &str) -> String {
match name {
Some(n) => format!("template: {n}:{line}:{col}: {message}"),
None => format!("template: {line}:{col}: {message}"),
}
}
#[derive(Debug, Error)]
pub enum TemplateError {
#[error("{}", fmt_src_err(name, *line, *col, message))]
Parse {
name: Option<String>,
line: usize,
col: usize,
message: String,
},
#[error("{}", fmt_src_err(name, *line, *col, message))]
Lex {
name: Option<String>,
line: usize,
col: usize,
message: String,
},
#[error("execution error: {0}")]
Exec(String),
#[error("index out of range: {index}")]
IndexOutOfRange {
index: i64,
},
#[error("type mismatch: expected {expected}, got {got}")]
TypeMismatch {
expected: &'static str,
got: &'static str,
},
#[error("map has no entry for key: {key}")]
MissingKey {
key: String,
},
#[error("recursion limit exceeded")]
RecursionLimit,
#[error("range iteration budget exhausted")]
RangeIterLimit,
#[cfg(feature = "std")]
#[error("function {name} panicked: {message}")]
FuncPanic {
name: String,
message: String,
},
#[error("undefined template: {0}")]
UndefinedTemplate(String),
#[error("undefined function: {0}")]
UndefinedFunction(String),
#[error("undefined variable: {0}")]
UndefinedVariable(String),
#[error("wrong number of arguments: {name} expects {expected}, got {got}")]
ArgCount {
name: String,
expected: usize,
got: usize,
},
#[error("cannot range over {0}")]
NotIterable(String),
#[cfg(feature = "std")]
#[error("failed to read template file {path}: {source}")]
ReadFile {
path: String,
#[source]
source: std::io::Error,
},
#[cfg(feature = "std")]
#[error("no files named in call to parse_files")]
NoFiles,
#[cfg(feature = "std")]
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("write error")]
Write,
}
impl From<core::fmt::Error> for TemplateError {
fn from(_: core::fmt::Error) -> Self {
TemplateError::Write
}
}
pub type Result<T> = core::result::Result<T, TemplateError>;