tron 2.1.0

A rust based template system built for speed and simplicity.
Documentation
//! Template assembler example showing multi-template composition.
//!
//! This example demonstrates how to use TronAssembler to combine multiple
//! templates into complex structured output.

use tron::{TronTemplate, TronRef, TronAssembler, Result};

fn main() -> Result<()> {
    println!("=== Tron Template Assembler Example ===\n");

    // Example 1: Basic assembly
    example_basic_assembly()?;
    
    // Example 2: Complete Rust file generation
    example_complete_file_generation()?;
    
    // Example 3: Global placeholder usage
    example_global_placeholders()?;
    
    // Example 4: Dependency collection
    example_dependency_collection()?;

    Ok(())
}

fn example_basic_assembly() -> Result<()> {
    println!("1. Basic Template Assembly:");
    
    let mut assembler = TronAssembler::new();
    
    // Add file header
    let header = TronTemplate::new("// Generated by Tron Template Engine\n// @[timestamp]@\n")?;
    let mut header_ref = TronRef::new(header);
    header_ref.set("timestamp", "2024-01-01 12:00:00")?;
    assembler.add_template(header_ref);
    
    // Add imports
    let imports = TronTemplate::new("use std::collections::HashMap;\nuse serde::{{Serialize, Deserialize}};\n")?;
    assembler.add_template(TronRef::new(imports));
    
    // Add main content
    let content = TronTemplate::new(r#"
#[derive(Debug, Serialize, Deserialize)]
pub struct @[struct_name]@ {
    @[fields]@
}
"#)?;
    let mut content_ref = TronRef::new(content);
    content_ref.set("struct_name", "Configuration")?;
    content_ref.set("fields", "pub name: String,\n    pub settings: HashMap<String, String>,")?;
    assembler.add_template(content_ref);
    
    let result = assembler.render_all()?;
    println!("{}", result);
    
    Ok(())
}

fn example_complete_file_generation() -> Result<()> {
    println!("2. Complete Rust File Generation:");
    
    let mut assembler = TronAssembler::with_separator("\n");
    
    // File documentation
    let doc_template = TronTemplate::new(r#"//! @[module_title]@
//!
//! @[module_description]@
//!
//! # Examples
//!
//! @[example_code]@
"#)?;
    let mut doc_ref = TronRef::new(doc_template);
    doc_ref.set("module_title", "Database Models")?;
    doc_ref.set("module_description", "This module contains all database model definitions.")?;
    doc_ref.set("example_code", r#"```rust
let user = User::new("Alice".to_string(), "alice@example.com".to_string());
println!("{:?}", user);
```"#)?;
    assembler.add_template(doc_ref);
    
    // Imports section
    let imports = TronTemplate::new(r#"use serde::{Serialize, Deserialize};
use uuid::Uuid;
use chrono::{DateTime, Utc};"#)?;
    assembler.add_template(TronRef::new(imports));
    
    // User struct
    let user_struct = TronTemplate::new(r#"/// Represents a user in the system
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
    pub id: Uuid,
    pub name: String,
    pub email: String,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}"#)?;
    assembler.add_template(TronRef::new(user_struct));
    
    // User implementation
    let user_impl = TronTemplate::new(r#"impl User {
    /// Creates a new user with generated UUID and current timestamps
    pub fn new(name: String, email: String) -> Self {
        let now = Utc::now();
        Self {
            id: Uuid::new_v4(),
            name,
            email,
            created_at: now,
            updated_at: now,
        }
    }
    
    /// Updates the user's information and timestamp
    pub fn update(&mut self, name: Option<String>, email: Option<String>) {
        if let Some(new_name) = name {
            self.name = new_name;
        }
        if let Some(new_email) = email {
            self.email = new_email;
        }
        self.updated_at = Utc::now();
    }
}"#)?;
    assembler.add_template(TronRef::new(user_impl));
    
    // Tests module
    let tests = TronTemplate::new(r#"#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_user_creation() {
        let user = User::new("Test User".to_string(), "test@example.com".to_string());
        assert_eq!(user.name, "Test User");
        assert_eq!(user.email, "test@example.com");
        assert!(user.created_at <= Utc::now());
    }
    
    #[test]
    fn test_user_update() {
        let mut user = User::new("Old Name".to_string(), "old@example.com".to_string());
        let old_updated = user.updated_at;
        
        std::thread::sleep(std::time::Duration::from_millis(1));
        user.update(Some("New Name".to_string()), None);
        
        assert_eq!(user.name, "New Name");
        assert_eq!(user.email, "old@example.com");
        assert!(user.updated_at > old_updated);
    }
}"#)?;
    assembler.add_template(TronRef::new(tests));
    
    let result = assembler.render_all()?;
    println!("{}", result);
    
    Ok(())
}

fn example_global_placeholders() -> Result<()> {
    println!("3. Global Placeholder Usage:");
    
    let mut assembler = TronAssembler::new();
    
    // Create templates that share common placeholders
    let struct1 = TronTemplate::new(r#"pub struct @[prefix]@User {
    pub name: String,
    pub version: @[version]@,
}"#)?;
    
    let struct2 = TronTemplate::new(r#"pub struct @[prefix]@Config {
    pub setting: String,
    pub version: @[version]@,
}"#)?;
    
    let enum_template = TronTemplate::new(r#"pub enum @[prefix]@Error {
    InvalidVersion(@[version]@),
    ConfigError,
}"#)?;
    
    assembler.add_template(TronRef::new(struct1));
    assembler.add_template(TronRef::new(struct2));
    assembler.add_template(TronRef::new(enum_template));
    
    // Set global values that apply to all templates
    assembler.set_global("prefix", "App")?;
    assembler.set_global("version", "u32")?;
    
    let result = assembler.render_all()?;
    println!("{}", result);
    
    Ok(())
}

fn example_dependency_collection() -> Result<()> {
    println!("4. Dependency Collection:");
    
    let mut assembler = TronAssembler::new();
    
    // Template with serde dependency
    let serde_struct = TronRef::new(TronTemplate::new(r#"#[derive(Serialize, Deserialize)]
pub struct SerializableData {
    pub value: String,
}"#)?)
        .with_dependency("serde = { version = \"1.0\", features = [\"derive\"] }");
    
    // Template with uuid dependency
    let uuid_struct = TronRef::new(TronTemplate::new(r#"pub struct EntityId {
    pub id: Uuid,
}"#)?)
        .with_dependency("uuid = \"1.0\"");
    
    // Template with tokio dependency
    let async_fn = TronRef::new(TronTemplate::new(r#"pub async fn async_operation() -> Result<(), Box<dyn std::error::Error>> {
    tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
    Ok(())
}"#)?)
        .with_dependency("tokio = { version = \"1.0\", features = [\"full\"] }");
    
    // Template with duplicate serde dependency (will be deduplicated)
    let another_serde = TronRef::new(TronTemplate::new(r#"#[derive(Serialize)]
pub struct AnotherStruct {
    pub data: i32,
}"#)?)
        .with_dependency("serde = { version = \"1.0\", features = [\"derive\"] }");
    
    assembler.add_template(serde_struct);
    assembler.add_template(uuid_struct);
    assembler.add_template(async_fn);
    assembler.add_template(another_serde);
    
    let result = assembler.render_all()?;
    println!("{}", result);
    
    let all_deps = assembler.all_dependencies();
    println!("\nAll dependencies (deduplicated): {} total", all_deps.len());
    for dep in all_deps {
        println!("  - {}", dep);
    }
    
    Ok(())
}