tron 2.1.0

A rust based template system built for speed and simplicity.
Documentation
//! Template composition example showing nested template usage.
//!
//! This example demonstrates how to compose templates together to build
//! complex code structures from smaller, reusable components.

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

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

    // Example 1: Basic composition
    example_basic_composition()?;
    
    // Example 2: Multi-level nesting
    example_nested_composition()?;
    
    // Example 3: Reusable components
    example_reusable_components()?;

    Ok(())
}

fn example_basic_composition() -> Result<()> {
    println!("1. Basic Template Composition:");
    
    // Create a function template
    let function_template = TronTemplate::new(
        "fn @[name]@(@[params]@) -> @[return_type]@ {\n    @[body]@\n}"
    )?;
    
    // Create a body template 
    let body_template = TronTemplate::new("@[computation]@\n    @[return_statement]@")?;
    
    // Configure the body template
    let mut body_ref = TronRef::new(body_template);
    body_ref.set("computation", "let result = a * b + c;")?;
    body_ref.set("return_statement", "result")?;
    
    // Compose them together
    let mut function_ref = TronRef::new(function_template);
    function_ref.set("name", "calculate")?;
    function_ref.set("params", "a: i32, b: i32, c: i32")?;
    function_ref.set("return_type", "i32")?;
    function_ref.set_ref("body", body_ref)?;
    
    let result = function_ref.render()?;
    println!("{}", result);
    println!();
    
    Ok(())
}

fn example_nested_composition() -> Result<()> {
    println!("2. Multi-Level Nested Composition:");
    
    // Level 1: Module template
    let module_template = TronTemplate::new(
        "pub mod @[module_name]@ {\n    @[imports]@\n\n    @[content]@\n}"
    )?;
    
    // Level 2: Struct template
    let struct_template = TronTemplate::new(
        "#[derive(@[derives]@)]\npub struct @[struct_name]@ {\n    @[fields]@\n}\n\n@[impl_block]@"
    )?;
    
    // Level 3: Implementation template
    let impl_template = TronTemplate::new(
        "impl @[struct_name]@ {\n    @[methods]@\n}"
    )?;
    
    // Level 4: Method template
    let method_template = TronTemplate::new(
        "pub fn @[method_name]@(&self) -> @[return_type]@ {\n        @[method_body]@\n    }"
    )?;
    
    // Build from innermost to outermost
    let mut method_ref = TronRef::new(method_template);
    method_ref.set("method_name", "get_display_name")?;
    method_ref.set("return_type", "String")?;
    method_ref.set("method_body", "format!(\"{} <{}>\", self.name, self.email)")?;
    
    let mut impl_ref = TronRef::new(impl_template);
    impl_ref.set("struct_name", "User")?;
    impl_ref.set_ref("methods", method_ref)?;
    
    let mut struct_ref = TronRef::new(struct_template);
    struct_ref.set("derives", "Debug, Clone")?;
    struct_ref.set("struct_name", "User")?;
    struct_ref.set("fields", "pub name: String,\n    pub email: String,")?;
    struct_ref.set_ref("impl_block", impl_ref)?;
    
    let mut module_ref = TronRef::new(module_template);
    module_ref.set("module_name", "user")?;
    module_ref.set("imports", "use std::fmt;")?;
    module_ref.set_ref("content", struct_ref)?;
    
    let result = module_ref.render()?;
    println!("{}", result);
    
    Ok(())
}

fn example_reusable_components() -> Result<()> {
    println!("3. Reusable Template Components:");
    
    // Create reusable field template
    fn create_field_template(name: &str, field_type: &str, doc: Option<&str>) -> Result<TronRef> {
        let template = if let Some(doc_comment) = doc {
            TronTemplate::new("    /// @[doc]@\n    pub @[name]@: @[type]@,")?
        } else {
            TronTemplate::new("    pub @[name]@: @[type]@,")?
        };
        
        let mut field_ref = TronRef::new(template);
        field_ref.set("name", name)?;
        field_ref.set("type", field_type)?;
        
        if let Some(doc_comment) = doc {
            field_ref.set("doc", doc_comment)?;
        }
        
        Ok(field_ref)
    }
    
    // Create multiple fields using the reusable component
    let id_field = create_field_template("id", "u64", Some("Unique identifier for the user"))?;
    let name_field = create_field_template("name", "String", Some("Full name of the user"))?;
    let email_field = create_field_template("email", "String", Some("Email address"))?;
    let active_field = create_field_template("active", "bool", None)?;
    
    // Compose fields into a struct
    let struct_template = TronTemplate::new(
        "#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]\npub struct User {\n@[fields]@\n}"
    )?;
    
    let mut struct_ref = TronRef::new(struct_template);
    
    // Manually combine the field templates (in a real scenario, you might want a helper for this)
    let mut combined_fields = String::new();
    combined_fields.push_str(&id_field.render()?);
    combined_fields.push('\n');
    combined_fields.push_str(&name_field.render()?);
    combined_fields.push('\n');
    combined_fields.push_str(&email_field.render()?);
    combined_fields.push('\n');
    combined_fields.push_str(&active_field.render()?);
    
    struct_ref.set("fields", &combined_fields)?;
    
    let result = struct_ref.render()?;
    println!("{}", result);
    
    Ok(())
}