opencrates 3.0.1

Enterprise-grade AI-powered Rust development companion with comprehensive automation, monitoring, and deployment capabilities
//! Manages crate templates and their customization.

use anyhow::Result;
use handlebars::Handlebars;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use tokio::fs;

/// Manages the loading and rendering of crate templates.
pub struct TemplateManager {
    handlebars: Handlebars<'static>,
    templates_dir: PathBuf,
}

/// Represents the specification for a new crate.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CrateSpec {
    /// The name of the crate.
    pub name: String,
    /// A brief description of the crate.
    pub description: String,
    /// The version of the crate.
    pub version: String,
    /// The authors of the crate.
    pub authors: Vec<String>,
    /// The license for the crate.
    pub license: String,
    /// The repository URL for the crate.
    pub repository: String,
    /// The homepage URL for the crate.
    pub homepage: String,
    /// A list of features for the crate.
    pub features: Vec<String>,
    /// A list of dependencies for the crate.
    pub dependencies: HashMap<String, String>,
}

impl TemplateManager {
    /// Creates a new `TemplateManager` and registers templates from the given directory.
    pub fn new(templates_dir: &Path) -> Result<Self> {
        let mut handlebars = Handlebars::new();
        handlebars.set_strict_mode(true);
        // ... implementation for registering templates ...
        Ok(Self {
            handlebars,
            templates_dir: templates_dir.to_path_buf(),
        })
    }

    /// Renders a template with the given name and data.
    pub fn render(&self, template_name: &str, data: &CrateSpec) -> Result<String> {
        self.handlebars
            .render(template_name, data)
            .map_err(anyhow::Error::from)
    }

    pub async fn render_crate(
        &self,
        _template: &str,
        context: &CrateSpec,
        output_dir: &Path,
    ) -> Result<()> {
        fs::create_dir_all(output_dir).await?;
        fs::create_dir_all(output_dir.join("src")).await?;

        // Render Cargo.toml
        let cargo_content = self.handlebars.render("cargo_toml", context)?;
        fs::write(output_dir.join("Cargo.toml"), cargo_content).await?;

        // Render lib.rs
        let lib_content = self.handlebars.render("lib_rs", context)?;
        fs::write(output_dir.join("src/lib.rs"), lib_content).await?;

        // Render main.rs if it's a binary crate
        if context
            .get("binary")
            .and_then(|v| v.as_bool())
            .unwrap_or(false)
        {
            let main_content = self.handlebars.render("main_rs", context)?;
            fs::write(output_dir.join("src/main.rs"), main_content).await?;
        }

        // Render README.md
        let readme_content = self.handlebars.render("readme", context)?;
        fs::write(output_dir.join("README.md"), readme_content).await?;

        Ok(())
    }
}