use tron::{TronTemplate, TronRef, Result};
fn main() -> Result<()> {
println!("=== Tron Template Composition Example ===\n");
example_basic_composition()?;
example_nested_composition()?;
example_reusable_components()?;
Ok(())
}
fn example_basic_composition() -> Result<()> {
println!("1. Basic Template Composition:");
let function_template = TronTemplate::new(
"fn @[name]@(@[params]@) -> @[return_type]@ {\n @[body]@\n}"
)?;
let body_template = TronTemplate::new("@[computation]@\n @[return_statement]@")?;
let mut body_ref = TronRef::new(body_template);
body_ref.set("computation", "let result = a * b + c;")?;
body_ref.set("return_statement", "result")?;
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:");
let module_template = TronTemplate::new(
"pub mod @[module_name]@ {\n @[imports]@\n\n @[content]@\n}"
)?;
let struct_template = TronTemplate::new(
"#[derive(@[derives]@)]\npub struct @[struct_name]@ {\n @[fields]@\n}\n\n@[impl_block]@"
)?;
let impl_template = TronTemplate::new(
"impl @[struct_name]@ {\n @[methods]@\n}"
)?;
let method_template = TronTemplate::new(
"pub fn @[method_name]@(&self) -> @[return_type]@ {\n @[method_body]@\n }"
)?;
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:");
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)
}
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)?;
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);
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(())
}