use crate::packs::metadata::load_pack_metadata;
use ggen_utils::error::Result;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenerateInput {
pub pack_id: String,
pub project_name: String,
pub template_name: Option<String>,
pub output_dir: Option<PathBuf>,
pub variables: BTreeMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenerateOutput {
pub pack_id: String,
pub project_name: String,
pub templates_generated: Vec<String>,
pub files_created: usize,
pub output_path: PathBuf,
}
pub async fn generate_from_pack(input: &GenerateInput) -> Result<GenerateOutput> {
let pack = load_pack_metadata(&input.pack_id)?;
let output_dir = input
.output_dir
.clone()
.unwrap_or_else(|| PathBuf::from(&input.project_name));
std::fs::create_dir_all(&output_dir)?;
let mut templates_generated = Vec::new();
let mut total_files = 0;
let templates_to_use: Vec<_> = if let Some(ref template_name) = input.template_name {
pack.templates
.iter()
.filter(|t| t.name == *template_name)
.collect()
} else {
pack.templates.iter().collect()
};
if templates_to_use.is_empty() {
if let Some(ref template_name) = input.template_name {
return Err(ggen_utils::error::Error::new(&format!(
"Template '{}' not found in pack '{}'",
template_name, input.pack_id
)));
} else {
return Err(ggen_utils::error::Error::new(&format!(
"No templates found in pack '{}'",
input.pack_id
)));
}
}
for template in templates_to_use {
templates_generated.push(template.name.clone());
total_files += 1;
tracing::info!("Would generate template '{}'", template.name);
}
Ok(GenerateOutput {
pack_id: input.pack_id.clone(),
project_name: input.project_name.clone(),
templates_generated,
files_created: total_files,
output_path: output_dir,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_generate_from_pack_input_validation() {
let input = GenerateInput {
pack_id: "test-pack".to_string(),
project_name: "my-project".to_string(),
template_name: None,
output_dir: None,
variables: BTreeMap::new(),
};
let _ = generate_from_pack(&input).await;
}
}