macro_rules! run_node_simple {
($node_type:ty, $node_name:expr, $env_var:expr, $config_file:expr, $env_prefix:expr) => { ... };
}Expand description
Run a node with automatic config loading and context creation
This macro eliminates boilerplate by automatically handling:
- Config loading with fallback (from env var, file, or default)
- Context creation with node name
- Calling run_node with proper types
§Arguments
$node_type- The NodeImpl type (e.g., CameraFakeNode)$node_name- The node name string (e.g., “camera_fake”)$env_var- Environment variable for config file path (e.g., “CAMERA_CONFIG”)$config_file- Default config file path (e.g., “config/drivers/realsense_d435.json”)$env_prefix- Environment variable prefix for config overrides (e.g., “CAMERA”)
§Example
use mecha10::prelude::*;
#[derive(Debug)]
struct CameraFakeNode {
config: CameraConfig,
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
struct CameraConfig {
fps: f32,
}
#[async_trait]
impl NodeImpl for CameraFakeNode {
type Config = CameraConfig;
async fn init(config: Self::Config) -> Result<Self> {
Ok(Self { config })
}
async fn run(&mut self, ctx: &Context) -> Result<()> {
// Node logic here
Ok(())
}
}
// Instead of 13 lines:
// pub async fn run() -> Result<()> {
// info!("Starting fake camera driver");
// let config = load_config_with_fallback(
// "CAMERA_CONFIG",
// "config/drivers/realsense_d435.json",
// "CAMERA",
// Some(CameraConfig::default())
// )?;
// let ctx = Context::new("camera_fake");
// run_node::<CameraFakeNode>(config, ctx).await
// }
// Simply use 1 line:
run_node_simple!(
CameraFakeNode,
"camera_fake",
"CAMERA_CONFIG",
"config/drivers/realsense_d435.json",
"CAMERA"
);