use super::config::*;
use super::templates::*;
use crate::error::{OptimError, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum GeneratorType {
CorePlugin,
Tests,
Documentation,
Benchmarks,
Examples,
CICD,
CargoConfig,
Readme,
License,
GPUKernels,
Distributed,
FFIBindings,
Custom(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GeneratedFile {
pub path: PathBuf,
pub content: String,
pub file_type: GeneratedFileType,
pub executable: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum GeneratedFileType {
RustSource,
CargoToml,
Markdown,
YAML,
JSON,
Shell,
Python,
Text,
Binary,
}
pub trait CodeGenerator: std::fmt::Debug {
fn generate(&self, template: &PluginTemplate, config: &TemplateGeneratorConfig) -> Result<Vec<GeneratedFile>>;
fn generator_type(&self) -> GeneratorType;
fn can_handle(&self, template: &PluginTemplate) -> bool;
}
#[derive(Debug)]
pub struct CorePluginGenerator {
templates: HashMap<String, String>,
}
impl CorePluginGenerator {
pub fn new() -> Self {
let mut templates = HashMap::new();
templates.insert("optimizer".to_string(), include_str!("templates/optimizer.rs").to_string());
templates.insert("lib".to_string(), include_str!("templates/lib.rs").to_string());
templates.insert("error".to_string(), include_str!("templates/error.rs").to_string());
Self { templates }
}
fn generate_optimizer_code(&self, template: &PluginTemplate, config: &TemplateGeneratorConfig) -> Result<String> {
let template_content = self.templates.get("optimizer")
.ok_or_else(|| OptimError::InvalidConfig("Optimizer template not found".to_string()))?;
let mut code = template_content.clone();
code = code.replace("{{PLUGIN_NAME}}", &template.structure.name);
code = code.replace("{{PLUGIN_DESCRIPTION}}", &template.structure.description);
code = code.replace("{{AUTHOR}}", &template.metadata.author);
Ok(code)
}
}
impl CodeGenerator for CorePluginGenerator {
fn generate(&self, template: &PluginTemplate, config: &TemplateGeneratorConfig) -> Result<Vec<GeneratedFile>> {
let mut files = Vec::new();
let optimizer_code = self.generate_optimizer_code(template, config)?;
files.push(GeneratedFile {
path: PathBuf::from("src/lib.rs"),
content: optimizer_code,
file_type: GeneratedFileType::RustSource,
executable: false,
});
if let Some(error_template) = self.templates.get("error") {
files.push(GeneratedFile {
path: PathBuf::from("src/error.rs"),
content: error_template.clone(),
file_type: GeneratedFileType::RustSource,
executable: false,
});
}
Ok(files)
}
fn generator_type(&self) -> GeneratorType {
GeneratorType::CorePlugin
}
fn can_handle(&self, _template: &PluginTemplate) -> bool {
true }
}
#[derive(Debug)]
pub struct DocumentationGenerator;
impl CodeGenerator for DocumentationGenerator {
fn generate(&self, template: &PluginTemplate, config: &TemplateGeneratorConfig) -> Result<Vec<GeneratedFile>> {
if !config.include_docs {
return Ok(Vec::new());
}
let mut files = Vec::new();
let readme_content = self.generate_readme(template)?;
files.push(GeneratedFile {
path: PathBuf::from("README.md"),
content: readme_content,
file_type: GeneratedFileType::Markdown,
executable: false,
});
let api_docs = self.generate_api_docs(template)?;
files.push(GeneratedFile {
path: PathBuf::from("docs/api.md"),
content: api_docs,
file_type: GeneratedFileType::Markdown,
executable: false,
});
Ok(files)
}
fn generator_type(&self) -> GeneratorType {
GeneratorType::Documentation
}
fn can_handle(&self, _template: &PluginTemplate) -> bool {
true
}
}
impl DocumentationGenerator {
fn generate_readme(&self, template: &PluginTemplate) -> Result<String> {
let content = format!(
r#"# {}
{}
## Features
- Advanced optimization algorithm
- High-performance implementation
- GPU acceleration support
- Comprehensive testing
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
{} = "0.1.0"
```
## Usage
```rust
use {}::{{Optimizer}};
let optimizer = Optimizer::new();
// Use the optimizer...
```
## License
Licensed under {} license.
"#,
template.structure.name,
template.structure.description,
template.structure.name.to_lowercase().replace(' ', "_"),
template.structure.name.to_lowercase().replace(' ', "_"),
template.metadata.license
);
Ok(content)
}
fn generate_api_docs(&self, template: &PluginTemplate) -> Result<String> {
let content = format!(
r#"# {} API Documentation
## Overview
{}
## Main Components
### Optimizer
The main optimizer implementation.
### Configuration
Configuration options for the optimizer.
## Examples
See the examples directory for usage examples.
"#,
template.structure.name,
template.structure.description
);
Ok(content)
}
}
#[derive(Debug)]
pub struct TestGenerator;
impl CodeGenerator for TestGenerator {
fn generate(&self, template: &PluginTemplate, config: &TemplateGeneratorConfig) -> Result<Vec<GeneratedFile>> {
let mut files = Vec::new();
let test_content = self.generate_unit_tests(template)?;
files.push(GeneratedFile {
path: PathBuf::from("src/lib.rs").join("tests"),
content: test_content,
file_type: GeneratedFileType::RustSource,
executable: false,
});
if config.include_benchmarks {
let bench_content = self.generate_benchmarks(template)?;
files.push(GeneratedFile {
path: PathBuf::from("benches/benchmark.rs"),
content: bench_content,
file_type: GeneratedFileType::RustSource,
executable: false,
});
}
Ok(files)
}
fn generator_type(&self) -> GeneratorType {
GeneratorType::Tests
}
fn can_handle(&self, _template: &PluginTemplate) -> bool {
true
}
}
impl TestGenerator {
fn generate_unit_tests(&self, template: &PluginTemplate) -> Result<String> {
let content = format!(
r#"#[cfg(test)]
mod tests {{
use super::*;
#[test]
fn test_{}_creation() {{
let optimizer = Optimizer::new();
assert!(optimizer.is_ok());
}}
#[test]
fn test_{}_optimization() {{
// Add optimization tests here
}}
}}
"#,
template.structure.name.to_lowercase().replace(' ', "_"),
template.structure.name.to_lowercase().replace(' ', "_")
);
Ok(content)
}
fn generate_benchmarks(&self, template: &PluginTemplate) -> Result<String> {
let content = format!(
r#"use criterion::{{black_box, criterion_group, criterion_main, Criterion}};
use {}::Optimizer;
fn benchmark_{}(c: &mut Criterion) {{
c.bench_function("{}", |b| {{
let optimizer = Optimizer::new().expect("unwrap failed");
b.iter(|| {{
// Benchmark code here
black_box(&optimizer);
}});
}});
}}
criterion_group!(benches, benchmark_{});
criterion_main!(benches);
"#,
template.structure.name.to_lowercase().replace(' ', "_"),
template.structure.name.to_lowercase().replace(' ', "_"),
template.structure.name,
template.structure.name.to_lowercase().replace(' ', "_")
);
Ok(content)
}
}
impl Default for CorePluginGenerator {
fn default() -> Self {
Self::new()
}
}