use super::core::*;
use crate::error::{OptimError, Result};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
pub mod config;
pub mod templates;
pub mod registry;
pub mod generators;
pub mod validation;
pub use config::*;
pub use templates::*;
pub use registry::*;
pub use generators::*;
pub use validation::*;
#[derive(Debug)]
pub struct AdvancedTemplateGenerator {
config: TemplateGeneratorConfig,
template_registry: TemplateRegistry,
generators: HashMap<GeneratorType, Box<dyn CodeGenerator>>,
validator: TemplateValidator,
}
impl AdvancedTemplateGenerator {
pub fn new(config: TemplateGeneratorConfig) -> Self {
let mut generators: HashMap<GeneratorType, Box<dyn CodeGenerator>> = HashMap::new();
generators.insert(GeneratorType::CorePlugin, Box::new(CorePluginGenerator::new()));
generators.insert(GeneratorType::Documentation, Box::new(DocumentationGenerator));
generators.insert(GeneratorType::Tests, Box::new(TestGenerator));
Self {
config,
template_registry: TemplateRegistry::new(),
generators,
validator: TemplateValidator::new(),
}
}
pub fn generate_plugin(&self, template_id: &str, output_path: &Path) -> Result<Vec<GeneratedFile>> {
let template = self.template_registry
.get_template(template_id)
.ok_or_else(|| OptimError::InvalidConfig(format!("Template '{}' not found", template_id)))?;
let validation_report = self.validator.validate(template);
if !validation_report.is_valid() {
return Err(OptimError::InvalidConfig(
format!("Template validation failed: {:?}", validation_report.errors())
));
}
let mut all_files = Vec::new();
for (generator_type, generator) in &self.generators {
if generator.can_handle(template) {
let files = generator.generate(template, &self.config)?;
all_files.extend(files);
}
}
Ok(all_files)
}
pub fn register_template(&mut self, template: PluginTemplate) -> Result<()> {
self.template_registry.register_template(template)
}
pub fn add_generator(&mut self, generator_type: GeneratorType, generator: Box<dyn CodeGenerator>) {
self.generators.insert(generator_type, generator);
}
pub fn get_statistics(&self) -> RegistryStatistics {
self.template_registry.get_statistics()
}
pub fn list_templates(&self) -> Vec<&String> {
self.template_registry.list_template_ids()
}
pub fn get_templates_by_category(&self, category: TemplateCategory) -> Option<&Vec<PluginTemplate>> {
self.template_registry.get_templates_by_category(category)
}
pub fn create_basic_optimizer_template(
name: String,
description: String,
author: String,
) -> PluginTemplate {
let metadata = TemplateMetadata::new(
format!("basic-{}", name.to_lowercase().replace(' ', "-")),
"0.1.0".to_string(),
author,
description.clone(),
);
let structure = EnhancedTemplateStructure {
name,
description,
category: TemplateCategory::Basic,
complexity: ComplexityLevel::Beginner,
required_features: vec!["optimization".to_string()],
optional_features: vec!["gpu".to_string(), "distributed".to_string()],
file_structure: HashMap::new(),
config_overrides: HashMap::new(),
};
PluginTemplate::new(metadata, structure)
.with_dependency("optirs-core".to_string())
.with_dependency("ndarray".to_string())
.with_dependency("num-traits".to_string())
}
pub fn write_files(&self, files: Vec<GeneratedFile>, base_path: &Path) -> Result<()> {
for file in files {
let full_path = base_path.join(&file.path);
if let Some(parent) = full_path.parent() {
std::fs::create_dir_all(parent)
.map_err(|e| OptimError::InvalidConfig(format!("Failed to create directory: {}", e)))?;
}
std::fs::write(&full_path, &file.content)
.map_err(|e| OptimError::InvalidConfig(format!("Failed to write file: {}", e)))?;
if file.executable {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let metadata = std::fs::metadata(&full_path)
.map_err(|e| OptimError::InvalidConfig(format!("Failed to get file metadata: {}", e)))?;
let mut permissions = metadata.permissions();
permissions.set_mode(permissions.mode() | 0o755);
std::fs::set_permissions(&full_path, permissions)
.map_err(|e| OptimError::InvalidConfig(format!("Failed to set permissions: {}", e)))?;
}
}
}
Ok(())
}
}
impl Default for AdvancedTemplateGenerator {
fn default() -> Self {
Self::new(TemplateGeneratorConfig::default())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_template_generator_creation() {
let generator = AdvancedTemplateGenerator::default();
assert_eq!(generator.list_templates().len(), 0);
}
#[test]
fn test_basic_template_creation() {
let template = AdvancedTemplateGenerator::create_basic_optimizer_template(
"TestOptimizer".to_string(),
"A test optimizer for unit testing".to_string(),
"Test Author".to_string(),
);
assert_eq!(template.structure.name, "TestOptimizer");
assert_eq!(template.structure.category, TemplateCategory::Basic);
assert_eq!(template.structure.complexity, ComplexityLevel::Beginner);
}
}