lib_humus/
humus_engine_loader.rs1use log::error;
6use log::warn;
7use tera::Tera;
8
9use std::marker::PhantomData;
10use std::path::PathBuf;
11use std::sync::Arc;
12
13use crate::HumusEngine;
14use crate::language::LanguageEngine;
15use crate::language::LanguageEngineLoaderError;
16use crate::templating::HumusApiFormat;
17use crate::templating::TemplatingEngine;
18use crate::templating::TemplatingEngineLoaderError;
19
20#[derive(Debug, Clone)]
52pub struct HumusEngineLoader<ApiFormat: HumusApiFormat> {
53 pub template_location: PathBuf,
55
56 pub extra_config_location: Option<PathBuf>,
59
60 pub tera: Tera,
63
64 phantom_api_format: PhantomData<ApiFormat>,
65}
66
67impl<ApiFormat: HumusApiFormat> HumusEngineLoader<ApiFormat> {
68 pub fn new(template_location: PathBuf, extra_config_location: Option<PathBuf>) -> Self {
70 Self {
71 template_location: template_location,
72 extra_config_location: extra_config_location,
73 tera: Tera::new(),
74 phantom_api_format: PhantomData,
75 }
76 }
77
78 pub fn cli_template_location(mut self, location: Option<PathBuf>) -> Self {
82 if let Some(location) = location {
83 self.template_location = location;
84 }
85 self
86 }
87
88 pub fn cli_extra_config_location(mut self, location: Option<PathBuf>) -> Self {
92 if let Some(location) = location {
93 self.extra_config_location = Some(location);
94 }
95 self
96 }
97
98 pub fn base_dir(&self) -> PathBuf {
100 self.template_location.clone()
101 }
102
103 #[expect(clippy::result_large_err)]
113 pub fn load_templates(&self) -> Result<HumusEngine<ApiFormat>, HumusEngineLoaderError> {
114 let languages_base_dir = self.template_location.join("languages");
115 let language_engine = match LanguageEngine::load_from_directory(&languages_base_dir) {
116 Ok(engine) => engine,
117 Err(e) => {
118 error!("Error loading language engine: {e}");
119 match &e {
120 LanguageEngineLoaderError::BaseDirectoryDoesNotExist { path, .. } => {
121 warn!(
122 "Using an empty language engine, localization functions will not work."
123 );
124 warn!(
125 "Please consider creating the file {:?}, see the lib-humus crate documentation for details.",
126 path.join("manifest.toml")
127 );
128 LanguageEngine::new_empty()
129 }
130 _ => {
131 return Err(HumusEngineLoaderError::LanguageEngineError {
132 path: languages_base_dir,
133 error: e,
134 });
135 }
136 }
137 }
138 };
139
140 let language_engine = Arc::new(language_engine);
141
142 let templating_engine = TemplatingEngine::load_from_directory(
143 &self.template_location,
144 self.extra_config_location.as_deref(),
145 self.tera.clone(),
146 Some(language_engine.clone()),
147 )
148 .map_err(HumusEngineLoaderError::TemplatingEngineError)?;
149
150 Ok(HumusEngine::new(templating_engine, language_engine))
151 }
152}
153
154#[derive(Debug, thiserror::Error)]
156pub enum HumusEngineLoaderError {
157 #[error("Error loading templates: {0}")]
159 TemplatingEngineError(#[source] TemplatingEngineLoaderError),
160 #[error("Error loading languge engine {path:?}:\n{error}")]
162 LanguageEngineError {
163 path: PathBuf,
165 #[source]
167 error: LanguageEngineLoaderError,
168 },
169}