mecha10-templates 0.6.2

Mecha10 project templates — code generation, init, and template services
Documentation
//! Node code generation templates

use crate::utils::to_pascal_case;

/// Render a node source file for one of the standard node kinds.
///
/// All node templates (planner, controller, perception, ML) share the same
/// struct/impl/`main` scaffolding and differ only in the doc title, the
/// label used in init/shutdown log lines, the init/execute TODO body, the
/// loop comment, and the loop sleep duration. This helper factors that
/// shape out so each `*_node` function only needs to supply the varying
/// pieces.
#[allow(clippy::too_many_arguments)]
fn node_template(
    name: &str,
    title: &str,
    log_label: &str,
    init_todo: &str,
    execute_todos: &str,
    loop_comment: &str,
    sleep_ms: u64,
) -> String {
    let pascal = to_pascal_case(name);
    format!(
        r#"//! {name} - {title}
//!
//! Auto-generated node template.

use anyhow::Result;
use mecha10_core::prelude::*;
use tracing::info;

struct {pascal} {{
    ctx: NodeContext,
}}

impl {pascal} {{
    pub fn new(ctx: NodeContext) -> Self {{
        Self {{ ctx }}
    }}
}}

#[async_trait::async_trait]
impl Node for {pascal} {{
    async fn initialize(&mut self) -> Result<()> {{
        info!("Initializing {name} {log_label}");
        {init_todo}
        Ok(())
    }}

    async fn execute(&mut self) -> Result<()> {{
        {execute_todos}
        Ok(())
    }}

    async fn shutdown(&mut self) -> Result<()> {{
        info!("Shutting down {name} {log_label}");
        Ok(())
    }}
}}

#[tokio::main]
async fn main() -> Result<()> {{
    let ctx = NodeContext::new("{name}")?;
    let mut node = {pascal}::new(ctx);

    node.initialize().await?;

    {loop_comment}
    loop {{
        node.execute().await?;
        tokio::time::sleep(tokio::time::Duration::from_millis({sleep_ms})).await;
    }}
}}
"#,
    )
}

/// Generate planner node template
pub fn planner_node(name: &str) -> String {
    node_template(
        name,
        "Task Planner Node",
        "planner",
        "// TODO: Initialize planning system",
        "// TODO: Plan tasks\n        // TODO: Publish plans",
        "// Run node loop",
        100,
    )
}

/// Generate controller node template
pub fn controller_node(name: &str) -> String {
    node_template(
        name,
        "Controller Node",
        "controller",
        "// TODO: Initialize controller",
        "// TODO: Read state\n        // TODO: Compute control\n        // TODO: Send commands",
        "// Run control loop",
        10,
    )
}

/// Generate perception node template
pub fn perception_node(name: &str) -> String {
    node_template(
        name,
        "Perception Node",
        "perception",
        "// TODO: Load perception models",
        "// TODO: Read sensor data\n        // TODO: Run perception\n        // TODO: Publish detections",
        "// Run perception loop",
        100,
    )
}

/// Generate ML inference node template
pub fn ml_node(name: &str) -> String {
    node_template(
        name,
        "ML Inference Node",
        "ML node",
        "// TODO: Load ML model",
        "// TODO: Read input data\n        // TODO: Run inference\n        // TODO: Publish predictions",
        "// Run inference loop",
        50,
    )
}