mecha10-core 0.6.3

Mecha10 core runtime and foundational types
Documentation
//! Infrastructure configuration types
//!
//! Configuration structures for Redis, PostgreSQL, MLflow, MinIO, and other
//! infrastructure services used by the Mecha10 framework.

use serde::Deserialize;

/// Infrastructure configuration
#[derive(Debug, Deserialize, Clone)]
pub struct InfrastructureConfig {
    /// Local Redis instance for on-robot messaging
    pub redis: RedisConfig,
    /// Control plane Redis instance for robot-to-cloud communication
    /// Optional - only used when connecting to Mecha10 cloud services
    #[serde(default)]
    pub control_plane_redis: Option<RedisConfig>,
    /// Redis bridge configuration
    /// Controls message forwarding between local and control plane Redis
    #[serde(default)]
    pub bridge: Option<BridgeConfig>,
    #[serde(default)]
    pub postgres: Option<PostgresConfig>,
    #[serde(default)]
    pub mlflow: Option<MlflowConfig>,
    #[serde(default)]
    pub minio: Option<MinioConfig>,
}

#[derive(Debug, Deserialize, Clone)]
pub struct RedisConfig {
    pub url: String,
    #[serde(default = "default_max_connections")]
    pub max_connections: usize,
    #[serde(default = "default_connection_timeout")]
    pub connection_timeout_ms: u64,
}

impl Default for RedisConfig {
    fn default() -> Self {
        Self {
            url: "redis://localhost:6379".to_string(),
            max_connections: default_max_connections(),
            connection_timeout_ms: default_connection_timeout(),
        }
    }
}

#[derive(Debug, Deserialize, Clone)]
pub struct PostgresConfig {
    pub host: String,
    pub port: u16,
    pub database: String,
    pub username: String,
    pub password: String,
    #[serde(default = "default_max_connections")]
    pub max_connections: usize,
}

#[derive(Debug, Deserialize, Clone)]
pub struct MlflowConfig {
    pub tracking_uri: String,
    pub artifact_location: String,
}

#[derive(Debug, Deserialize, Clone)]
pub struct MinioConfig {
    pub endpoint: String,
    pub access_key: String,
    pub secret_key: String,
    #[serde(default)]
    pub secure: bool,
}

/// Redis bridge configuration
#[derive(Debug, Deserialize, Clone)]
pub struct BridgeConfig {
    /// Enable or disable the bridge
    #[serde(default = "default_bridge_enabled")]
    pub enabled: bool,

    /// Topic patterns that should stay local (not bridged)
    /// Examples: "/sensor/camera/*", "/sensor/lidar/*"
    #[serde(default = "default_local_topics")]
    pub local_topics: Vec<String>,

    /// Topic patterns that should be bridged to control plane
    /// Examples: "/system/*", "/telemetry/*", "/logs/*"
    #[serde(default = "default_bridged_topics")]
    pub bridged_topics: Vec<String>,

    /// Robot identifier for wildcard subscriptions
    /// Used in control plane for topic prefixing (e.g., "robot-123/camera/rgb")
    #[serde(default)]
    pub robot_id: Option<String>,
}

impl Default for BridgeConfig {
    fn default() -> Self {
        Self {
            enabled: default_bridge_enabled(),
            local_topics: default_local_topics(),
            bridged_topics: default_bridged_topics(),
            robot_id: None,
        }
    }
}

fn default_bridge_enabled() -> bool {
    true
}

fn default_local_topics() -> Vec<String> {
    vec![
        // High-frequency sensor data stays local
        "/sensor/camera/*".to_string(),
        "/sensor/lidar/*".to_string(),
        "/sensor/imu/*".to_string(),
    ]
}

fn default_bridged_topics() -> Vec<String> {
    vec![
        // System topics go to control plane
        "/system/*".to_string(),
        "/telemetry/*".to_string(),
        "/logs/*".to_string(),
        "/fleet/*".to_string(),
    ]
}

fn default_max_connections() -> usize {
    10
}

fn default_connection_timeout() -> u64 {
    5000
}