use lib_humus_configuration::read_from_toml_file;
use lib_humus_configuration::ErrorCause;
use lib_humus_configuration::HumusConfigError;
use log::{error, info};
use serde::Deserialize;
use tera::Tera;
use std::error::Error;
use std::fmt;
use crate::HumusProtoEngine;
#[derive(Debug, Clone, Deserialize)]
pub struct TemplateEngineLoader {
pub template_location: String,
pub extra_config_location: Option<String>,
}
impl TemplateEngineLoader {
pub fn new(template_location: String, extra_config_location: Option<String>) -> Self {
Self {
template_location: template_location,
extra_config_location: extra_config_location,
}
}
pub fn cli_template_location(mut self, location: Option<String>) -> Self {
if let Some(location) = location {
self.template_location = location;
}
self
}
pub fn cli_extra_config_location(mut self, location: Option<String>) -> Self {
if let Some(location) = location {
self.extra_config_location = Some(location);
}
self
}
pub fn base_dir(&self) -> String {
if self.template_location.ends_with("/") {
self.template_location.clone()
} else {
self.template_location.clone() + "/"
}
}
pub fn load_templates(&self) -> Result<HumusProtoEngine, TemplateEngineLoaderError> {
let template_base_dir = self.base_dir();
let template_extra_config_res = match &self.extra_config_location {
Some(path) => read_from_toml_file(path),
None => read_from_toml_file(&(template_base_dir.clone() + "extra.toml")),
};
let template_extra_config = match template_extra_config_res {
Ok(c) => Some(c),
Err(e) => match &e.cause {
ErrorCause::FileRead { .. } => {
if self.extra_config_location.is_some() {
return Err(TemplateEngineLoaderError::ConfigurationError(e));
}
None
}
_ => {
return Err(TemplateEngineLoaderError::ConfigurationError(e));
}
},
};
let template_glob = template_base_dir.clone() + "*";
info!("Parsing Templates from '{}' ...", &template_glob);
let res = Tera::new((template_glob).as_str());
let tera = match res {
Ok(t) => t,
Err(e) => {
error!("Error Parsing Template: {e}");
return Err(TemplateEngineLoaderError::TemplateParseError {
path: template_glob,
tera_error: e,
});
}
};
Ok(HumusProtoEngine {
tera: tera,
template_config: template_extra_config,
})
}
}
#[derive(Debug)]
pub enum TemplateEngineLoaderError {
ConfigurationError(HumusConfigError),
TemplateParseError {
path: String,
tera_error: tera::Error,
},
}
impl fmt::Display for TemplateEngineLoaderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::ConfigurationError(e) => {
write!(f, "Error with template extra configuration:\n{e}")
}
Self::TemplateParseError { path, tera_error } => {
write!(f, "Error parsing template '{path}':\n{tera_error}")
}
}
}
}
impl Error for TemplateEngineLoaderError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::ConfigurationError(error) => Some(error),
Self::TemplateParseError { tera_error, .. } => Some(tera_error),
}
}
}