roplat 0.2.0

roplat: just a robot operation system
Documentation
//! Node abstraction and built-in node collection.
//!
//! `Node` is the smallest computation unit in roplat: one input, one output.
//! Topology is not declared by nodes themselves; it is wired at compile time by
//! `#[roplat::system]`.

/// Arithmetic nodes (add/sub/mul/div/pow/abs, etc.).
pub mod arithmetic;
/// Filter nodes (moving average, rate limiter, low-pass, etc.).
pub mod filter;
/// I/O nodes (stdout/stderr/debug writers).
pub mod io;
/// Logic and comparison nodes.
pub mod logic;
// pub mod viz;  // disabled: depends on resource module which is currently commented out

use std::fmt::Debug;

use crate::error::RoplatError;

#[allow(async_fn_in_trait)]
/// roplat node trait.
///
/// # Design Boundaries
/// - `process` is on the hot path and returns only `Output` to avoid extra `Result` branching.
/// - Lifecycle errors are surfaced by [`Node::on_init`] and [`Node::on_shutdown`].
/// - Node instances are typically wired by system macros at compile time.
///
/// # Example
/// ```rust
/// use roplat::Node;
/// use roplat::RoplatError;
///
/// struct Inc;
///
/// impl Node for Inc {
///     type Input = i32;
///     type Output = i32;
///     type Error = RoplatError;
///
///     async fn process(&mut self, input: Self::Input) -> Self::Output {
///         input + 1
///     }
/// }
/// ```
pub trait Node: Send + Sync {
    /// Input message type.
    type Input;
    /// Output message type.
    type Output;
    /// Error type for lifecycle hooks, convertible to [`RoplatError`].
    type Error: Into<RoplatError> + Debug + Send + Sync;

    /// Process one input and return output.
    async fn process(&mut self, input: Self::Input) -> Self::Output;

    /// Initialization hook.
    ///
    /// Default is a no-op. Use it for one-time setup (device connect, handle alloc, etc.).
    async fn on_init(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }

    /// Shutdown hook.
    ///
    /// Default is a no-op. Use it for cleanup and flush.
    async fn on_shutdown(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }
}