anathema_templates/error/
mod.rs1use std::error::Error as StdError;
2use std::fmt::{self, Display, Formatter};
3use std::path::PathBuf;
4
5pub(crate) use self::parse::{ParseError, ParseErrorKind, src_line_no};
6
7mod parse;
8
9pub type Result<T, E = Error> = std::result::Result<T, E>;
10
11#[derive(Debug)]
12pub struct Error {
13 pub template_path: Option<PathBuf>,
14 pub kind: ErrorKind,
15}
16
17impl Error {
18 pub fn new(path: Option<PathBuf>, kind: impl Into<ErrorKind>) -> Self {
19 Self {
20 kind: kind.into(),
21 template_path: path,
22 }
23 }
24
25 pub fn no_template(kind: ErrorKind) -> Self {
26 Self {
27 kind,
28 template_path: None,
29 }
30 }
31
32 pub fn path(&self) -> String {
33 match self.template_path.as_ref() {
34 Some(path) => format!("{}", path.display()),
35 None => String::new(),
36 }
37 }
38}
39
40impl Display for Error {
41 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
42 self.kind.fmt(f)
43 }
44}
45
46impl StdError for Error {}
47
48#[derive(Debug)]
49pub enum ErrorKind {
50 ParseError(ParseError),
51 CircularDependency,
52 MissingComponent(String),
53 EmptyTemplate,
54 EmptyBody,
55 InvalidStatement(String),
56 Io(std::io::Error),
57 GlobalAlreadyAssigned(String),
58}
59
60impl ErrorKind {
61 pub(crate) fn to_error(self, template: Option<PathBuf>) -> Error {
62 Error::new(template, self)
63 }
64}
65
66impl Display for ErrorKind {
67 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
68 match self {
69 ErrorKind::ParseError(err) => write!(f, "{err}"),
70 ErrorKind::CircularDependency => write!(f, "circular dependency"),
71 ErrorKind::MissingComponent(name) => write!(f, "`@{name}` is not a registered component"),
72 ErrorKind::EmptyTemplate => write!(f, "empty template"),
73 ErrorKind::EmptyBody => write!(f, "if or else node has no children"),
74 ErrorKind::InvalidStatement(stmt) => write!(f, "invalid statement: {stmt}"),
75 ErrorKind::Io(err) => write!(f, "{err}"),
76 ErrorKind::GlobalAlreadyAssigned(name) => write!(f, "global value `{name}` already assigned"),
77 }
78 }
79}
80
81impl From<ParseError> for ErrorKind {
82 fn from(value: ParseError) -> Self {
83 Self::ParseError(value)
84 }
85}
86
87impl From<std::io::Error> for ErrorKind {
88 fn from(value: std::io::Error) -> Self {
89 Self::Io(value)
90 }
91}