#![allow(dead_code)]
use crate::framework::{TemplateEngine, TemplateVars};
use anyhow::Result;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
pub struct TemplateService {
engine: TemplateEngine,
}
impl TemplateService {
pub fn new() -> Self {
Self {
engine: TemplateEngine::default(),
}
}
pub fn with_template_dir(template_dir: impl Into<PathBuf>) -> Self {
Self {
engine: TemplateEngine::new(template_dir),
}
}
pub fn render(&self, template_path: &str, variables: &HashMap<&str, &str>) -> Result<String> {
self.engine.render(template_path, variables)
}
pub async fn render_to_file(
&self,
template_path: &str,
output_path: impl AsRef<Path>,
variables: &HashMap<&str, &str>,
) -> Result<()> {
self.engine.render_to_file(template_path, output_path, variables).await
}
pub fn list_templates(&self, category: &str) -> Result<Vec<String>> {
self.engine.list_templates(category)
}
pub fn template_exists(&self, template_path: &str) -> bool {
self.engine.template_exists(template_path)
}
pub fn create_vars(&self) -> TemplateVars {
TemplateVars::new()
}
pub async fn generate_node(&self, node_name: &str, node_type: &str, output_dir: impl AsRef<Path>) -> Result<()> {
self.generate_from_category(
"nodes",
node_type,
"Available node types: sensor, actuator, controller",
node_name,
output_dir,
)
.await
}
pub async fn generate_driver(
&self,
driver_name: &str,
driver_type: &str,
output_dir: impl AsRef<Path>,
) -> Result<()> {
self.generate_from_category(
"drivers",
driver_type,
"Available driver types: camera, motor, sensor, imu",
driver_name,
output_dir,
)
.await
}
async fn generate_from_category(
&self,
category: &str,
item_type: &str,
available_types_hint: &str,
item_name: &str,
output_dir: impl AsRef<Path>,
) -> Result<()> {
let mut vars = self.create_vars();
vars.add_name(item_name);
let template_path = format!("{}/{}.rs.template", category, item_type);
if !self.template_exists(&template_path) {
return Err(anyhow::anyhow!(
"Template not found: {}. {}",
template_path,
available_types_hint
));
}
let output_path = output_dir.as_ref().join(item_name).join("src").join("lib.rs");
if let Some(parent) = output_path.parent() {
tokio::fs::create_dir_all(parent).await?;
}
self.render_to_file(&template_path, output_path, &vars.to_hashmap())
.await
}
pub async fn generate_type(&self, type_name: &str, output_dir: impl AsRef<Path>) -> Result<()> {
let mut vars = self.create_vars();
vars.add_name(type_name);
let template_path = "types/custom.rs.template";
if !self.template_exists(template_path) {
return Err(anyhow::anyhow!("Template not found: {}", template_path));
}
let output_path = output_dir.as_ref().join(format!("{}.rs", type_name));
if let Some(parent) = output_path.parent() {
tokio::fs::create_dir_all(parent).await?;
}
self.render_to_file(template_path, output_path, &vars.to_hashmap())
.await
}
pub async fn generate_cargo_toml(
&self,
package_name: &str,
package_type: &str,
output_dir: impl AsRef<Path>,
) -> Result<()> {
let mut vars = self.create_vars();
vars.add_name(package_name);
let template_path = format!("cargo/{}.toml.template", package_type);
if !self.template_exists(&template_path) {
return Err(anyhow::anyhow!(
"Template not found: {}. Available types: node, driver, type",
template_path
));
}
let output_path = output_dir.as_ref().join("Cargo.toml");
self.render_to_file(&template_path, output_path, &vars.to_hashmap())
.await
}
pub fn render_string(&self, template_content: &str, variables: &HashMap<&str, &str>) -> Result<String> {
let mut result = template_content.to_string();
for (key, value) in variables {
let placeholder = format!("{{{{{}}}}}", key);
result = result.replace(&placeholder, value);
}
Ok(result)
}
}
impl Default for TemplateService {
fn default() -> Self {
Self::new()
}
}