mecha10-core 0.8.0

Mecha10 core runtime and foundational types
Documentation
//! Stream combinators for declarative message processing
//!
//! This module provides a fluent API for transforming and filtering message streams.
//!
//! # Examples
//!
//! ## Filtering
//!
//! ```rust
//! use mecha10_core::prelude::*;
//! use mecha10_core::topics::perception;
//!
//! # async fn example(ctx: &Context) -> Result<()> {
//! // Only process high-confidence detections
//! let mut detections = ctx.subscribe(perception::DETECTIONS)
//!     .await?
//!     .filter(|d| d.iter().any(|det| det.confidence > 0.8));
//!
//! while let Some(dets) = detections.recv().await {
//!     // All detections have confidence > 0.8
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Throttling
//!
//! ```rust
//! use mecha10_core::prelude::*;
//! use mecha10_core::topics::sensor;
//!
//! # async fn example(ctx: &Context) -> Result<()> {
//! // Limit to 10 Hz
//! let mut images = ctx.subscribe(sensor::CAMERA_RGB)
//!     .await?
//!     .throttle(Duration::from_millis(100))
//!     .build();
//!
//! while let Some(image) = images.recv().await {
//!     // At most one image every 100ms
//!     println!("Image: {}x{}", image.width, image.height);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Latest Only
//!
//! ```rust
//! use mecha10_core::prelude::*;
//! use mecha10_core::topics::sensor;
//!
//! # async fn example(ctx: &Context) -> Result<()> {
//! // Always get the latest, drop old messages
//! let mut odom = ctx.subscribe(sensor::ODOMETRY)
//!     .await?
//!     .latest()
//!     .build();
//!
//! while let Some(reading) = odom.recv().await {
//!     // Always the most recent odometry reading
//!     println!("Position: {:?}", reading.position);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Zipping Streams
//!
//! ```rust
//! use mecha10_core::prelude::*;
//! use mecha10_core::topics::sensor;
//!
//! # async fn example(ctx: &Context) -> Result<()> {
//! // Combine camera images with LiDAR scans
//! let mut images = ctx.subscribe(sensor::CAMERA_RGB).await?;
//! let mut scans = ctx.subscribe(sensor::LIDAR_SCAN).await?;
//!
//! let mut zipped = images.zip(scans);
//!
//! while let Some((image, scan)) = zipped.recv().await {
//!     // Process synchronized sensor data
//!     println!("Image: {}x{}, LiDAR: {} points",
//!         image.width, image.height, scan.ranges.len());
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Windowing
//!
//! ```rust
//! use mecha10_core::prelude::*;
//! use mecha10_core::topics::perception;
//!
//! # async fn example(ctx: &Context) -> Result<()> {
//! // Collect detection batches over 1-second windows for rate analysis
//! let mut windowed = ctx.subscribe(perception::DETECTIONS)
//!     .await?
//!     .window(Duration::from_secs(1));
//!
//! while let Some(batches) = windowed.recv().await {
//!     let detections: Vec<_> = batches.iter().flatten().collect();
//!     let rate = detections.len() as f32; // detections per second
//!     println!("Detection rate: {} Hz", rate);
//!
//!     // Calculate average confidence over the window
//!     let avg_conf = detections.iter()
//!         .map(|d| d.confidence)
//!         .sum::<f32>() / detections.len() as f32;
//!     println!("Average confidence: {:.2}", avg_conf);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! This module is organized into:
//! - `builder`: `StreamBuilder`'s data and pipeline configuration (`filter`, `map`, `throttle`, `debounce`, `latest`)
//! - `pipeline`: `StreamBuilder::build`, running the configured filter/map/throttle/debounce pipeline
//! - `zip`: `StreamBuilder::zip`, pairing two streams
//! - `window`: `StreamBuilder::window`, time-windowed batching
//! - `batch`: `BatchBuilder`, size/timeout-based batching
//! - `receiver_ext`: `ReceiverExt`, the fluent entry point on `Receiver<T>`

mod batch;
mod builder;
mod pipeline;
mod receiver_ext;
mod window;
mod zip;

pub use batch::BatchBuilder;
pub use builder::StreamBuilder;
pub use receiver_ext::ReceiverExt;