ros2msg 0.5.3

A Rust parser for ROS2 message, service, action, and IDL files with 100% ROS2 Jazzy compatibility
Documentation
//! Example: Generate Rust bindings from ROS2 message files
//!
//! This example demonstrates the bindgen-style API for generating Rust code
//! from ROS2 interface files (.msg, .srv, .action, .idl).

use ros2msg::generator::{Generator, ParseCallbacks};
use std::env;

struct MyCallbacks;

impl ParseCallbacks for MyCallbacks {
    fn item_name(&self, info: &ros2msg::generator::ItemInfo) -> Option<String> {
        Some(format!("Ros{}", info.name()))
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Get ROS2 path from environment or use default
    let ros_path = env::var("ROS_PATH").unwrap_or_else(|_| "/opt/ros/jazzy".to_string());

    println!("=== ROS2 Message to Rust Code Generator ===\n");

    // Example 1: Single file generation with bindgen-style API
    println!("1. Generating std_msgs/Header...");
    let header_msg = format!("{}/share/std_msgs/msg/Header.msg", ros_path);

    Generator::new()
        .header("// Auto-generated by ros2msg - DO NOT EDIT")
        .derive_debug(true)
        .derive_clone(true)
        .derive_eq(true)
        .ctypes_prefix("std::os::raw")
        .include(&header_msg)
        .allowlist_recursively(true)
        .output_dir("target/generated/example1")
        .generate()?;

    println!("   ✓ Generated to target/generated/example1/\n");

    // Example 2: Multiple files with .includes()
    println!("2. Generating multiple messages...");
    let messages = vec![
        format!("{}/share/std_msgs/msg/String.msg", ros_path),
        format!("{}/share/std_msgs/msg/Int32.msg", ros_path),
        format!("{}/share/std_msgs/msg/Float64.msg", ros_path),
        format!("{}/share/geometry_msgs/msg/Pose.msg", ros_path),
    ];

    Generator::new()
        .header("// Auto-generated")
        .derive_debug(true)
        .derive_clone(true)
        .derive_eq(true)
        .includes(messages)
        .output_dir("target/generated/example2")
        .emit_rerun_if_changed(true)
        .generate()?;

    println!("   ✓ Generated 4 files to target/generated/example2/\n");

    // Example 3: Mixed file types (msg, srv, action)
    println!("3. Generating mixed file types...");

    Generator::new()
        .header("// Auto-generated with custom derives")
        .derive_debug(true)
        .derive_clone(true)
        .include(format!("{}/share/std_msgs/msg/Header.msg", ros_path))
        .include(format!("{}/share/std_srvs/srv/SetBool.srv", ros_path))
        .include(format!(
            "{}/share/example_interfaces/action/Fibonacci.action",
            ros_path
        ))
        .output_dir("target/generated/example3")
        .generate()?;

    println!("   ✓ Generated msg, srv, and action files\n");

    // Example 4: With ParseCallbacks for name transformation
    println!("4. Generating with ParseCallbacks...");

    Generator::new()
        .header("// Auto-generated with ParseCallbacks")
        .derive_debug(true)
        .parse_callbacks(Box::new(MyCallbacks))
        .include(format!("{}/share/std_msgs/msg/String.msg", ros_path))
        .output_dir("target/generated/example4")
        .generate()?;

    println!("   ✓ Generated with 'Ros' prefix\n");

    // Example 5: IDL file support
    println!("5. Generating from IDL file...");

    Generator::new()
        .header("// Auto-generated from IDL")
        .derive_debug(true)
        .derive_clone(true)
        .include(format!(
            "{}/share/trajectory_msgs/msg/JointTrajectory.idl",
            ros_path
        ))
        .output_dir("target/generated/example5")
        .generate()?;

    println!("   ✓ Generated from .idl file\n");

    println!("✓ All examples completed successfully!");
    println!("  Check target/generated/ for output files");

    Ok(())
}