use log::error;
use log::warn;
use tera::Tera;
use std::marker::PhantomData;
use std::path::PathBuf;
use std::sync::Arc;
use crate::HumusEngine;
use crate::language::LanguageEngine;
use crate::language::LanguageEngineLoaderError;
use crate::templating::HumusApiFormat;
use crate::templating::TemplatingEngine;
use crate::templating::TemplatingEngineLoaderError;
#[derive(Debug, Clone)]
pub struct HumusEngineLoader<ApiFormat: HumusApiFormat> {
pub template_location: PathBuf,
pub extra_config_location: Option<PathBuf>,
pub tera: Tera,
phantom_api_format: PhantomData<ApiFormat>,
}
impl<ApiFormat: HumusApiFormat> HumusEngineLoader<ApiFormat> {
pub fn new(template_location: PathBuf, extra_config_location: Option<PathBuf>) -> Self {
Self {
template_location: template_location,
extra_config_location: extra_config_location,
tera: Tera::new(),
phantom_api_format: PhantomData,
}
}
pub fn cli_template_location(mut self, location: Option<PathBuf>) -> Self {
if let Some(location) = location {
self.template_location = location;
}
self
}
pub fn cli_extra_config_location(mut self, location: Option<PathBuf>) -> Self {
if let Some(location) = location {
self.extra_config_location = Some(location);
}
self
}
pub fn base_dir(&self) -> PathBuf {
self.template_location.clone()
}
#[expect(clippy::result_large_err)]
pub fn load_templates(&self) -> Result<HumusEngine<ApiFormat>, HumusEngineLoaderError> {
let languages_base_dir = self.template_location.join("languages");
let language_engine = match LanguageEngine::load_from_directory(&languages_base_dir) {
Ok(engine) => engine,
Err(e) => {
error!("Error loading language engine: {e}");
match &e {
LanguageEngineLoaderError::BaseDirectoryDoesNotExist { path, .. } => {
warn!(
"Using an empty language engine, localization functions will not work."
);
warn!(
"Please consider creating the file {:?}, see the lib-humus crate documentation for details.",
path.join("manifest.toml")
);
LanguageEngine::new_empty()
}
_ => {
return Err(HumusEngineLoaderError::LanguageEngineError {
path: languages_base_dir,
error: e,
});
}
}
}
};
let language_engine = Arc::new(language_engine);
let templating_engine = TemplatingEngine::load_from_directory(
&self.template_location,
self.extra_config_location.as_deref(),
self.tera.clone(),
Some(language_engine.clone()),
)
.map_err(HumusEngineLoaderError::TemplatingEngineError)?;
Ok(HumusEngine::new(templating_engine, language_engine))
}
}
#[derive(Debug, thiserror::Error)]
pub enum HumusEngineLoaderError {
#[error("Error loading templates: {0}")]
TemplatingEngineError(#[source] TemplatingEngineLoaderError),
#[error("Error loading languge engine {path:?}:\n{error}")]
LanguageEngineError {
path: PathBuf,
#[source]
error: LanguageEngineLoaderError,
},
}