mecha10-templates 0.6.2

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

use crate::utils::to_pascal_case;

/// Render a driver source file for one of the standard driver kinds.
///
/// All driver templates (sensor, actuator, controller) share the same
/// `Config` struct + driver struct + `impl Driver` scaffolding and differ
/// only in the config fields, the log label used in init/shutdown, the
/// init/update/shutdown TODO bodies, and any extra inherent methods (e.g.
/// the actuator's `set_command`). This helper factors that shape out so
/// each `*_driver` function only supplies the varying pieces.
#[allow(clippy::too_many_arguments)]
fn driver_template(
    name: &str,
    title: &str,
    config_fields: &str,
    extra_methods: &str,
    log_label: &str,
    init_todo: &str,
    update_todo: &str,
    shutdown_todo: &str,
) -> String {
    let pascal = to_pascal_case(name);
    format!(
        r#"//! {name} - {title}
//!
//! Auto-generated driver template.

use anyhow::Result;
use mecha10_core::Driver;
use serde::{{Deserialize, Serialize}};
use tracing::info;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct {pascal}Config {{
{config_fields}
}}

pub struct {pascal} {{
    config: {pascal}Config,
}}

impl {pascal} {{
    pub fn new(config: {pascal}Config) -> Self {{
        Self {{ config }}
    }}
{extra_methods}}}

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

    async fn update(&mut self) -> Result<()> {{
        {update_todo}
        Ok(())
    }}

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

/// Generate sensor driver template
pub fn sensor_driver(name: &str) -> String {
    driver_template(
        name,
        "Sensor Driver",
        "    pub update_rate_hz: f64,",
        "",
        "driver",
        "// TODO: Initialize hardware/sensor",
        "// TODO: Read sensor data\n        // TODO: Publish to message bus",
        "",
    )
}

/// Generate actuator driver template
pub fn actuator_driver(name: &str) -> String {
    driver_template(
        name,
        "Actuator Driver",
        "    pub max_speed: f64,\n    pub acceleration: f64,",
        "\n    pub async fn set_command(&mut self, command: f64) -> Result<()> {\n        // TODO: Send command to actuator\n        Ok(())\n    }\n",
        "driver",
        "// TODO: Initialize actuator",
        "// TODO: Process actuator commands from message bus",
        "// TODO: Stop actuator safely\n        ",
    )
}

/// Generate controller driver template
pub fn controller_driver(name: &str) -> String {
    driver_template(
        name,
        "Controller Driver",
        "    pub control_rate_hz: f64,",
        "",
        "controller",
        "// TODO: Initialize controller",
        "// TODO: Run control loop",
        "",
    )
}