odin-protocol 1.0.0

The world's first standardized AI-to-AI communication infrastructure for Rust - 100% functional with 57K+ msgs/sec throughput
Documentation
//! Configuration types and builders for ODIN Protocol

use std::time::Duration;
use serde::{Deserialize, Serialize};
use crate::Result;
use crate::error::OdinError;

/// Configuration for ODIN Protocol instance
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OdinConfig {
    /// Unique node identifier
    pub node_id: String,
    /// Network endpoint URL (WebSocket)
    pub network_endpoint: String,
    /// Authentication token (optional)
    pub token: Option<String>,
    /// Connection timeout
    pub timeout: Duration,
    /// Maximum number of connections
    pub max_connections: usize,
    /// Heartbeat interval
    pub heartbeat_interval: Duration,
    /// Maximum retry attempts
    pub max_retries: u32,
    /// Enable debug logging
    pub debug: bool,
    /// Enable performance monitoring
    pub performance_monitoring: bool,
    /// Maximum message size in bytes
    pub max_message_size: usize,
    /// Buffer size for network operations
    pub buffer_size: usize,
}

impl Default for OdinConfig {
    fn default() -> Self {
        Self {
            node_id: uuid::Uuid::new_v4().to_string(),
            network_endpoint: "ws://localhost:8080".to_string(),
            token: None,
            timeout: crate::defaults::TIMEOUT,
            max_connections: crate::defaults::MAX_CONNECTIONS,
            heartbeat_interval: crate::defaults::HEARTBEAT_INTERVAL,
            max_retries: crate::defaults::MAX_RETRIES,
            debug: false,
            performance_monitoring: true,
            max_message_size: crate::defaults::MAX_MESSAGE_SIZE,
            buffer_size: crate::defaults::BUFFER_SIZE,
        }
    }
}

impl OdinConfig {
    /// Create a new configuration builder
    pub fn builder() -> OdinConfigBuilder {
        OdinConfigBuilder::new()
    }
    
    /// Validate the configuration
    pub fn validate(&self) -> Result<()> {
        if self.node_id.is_empty() {
            return Err(OdinError::Configuration("Node ID cannot be empty".to_string()));
        }
        
        if self.network_endpoint.is_empty() {
            return Err(OdinError::Configuration("Network endpoint cannot be empty".to_string()));
        }
        
        if self.max_connections == 0 {
            return Err(OdinError::Configuration("Max connections must be greater than 0".to_string()));
        }
        
        if self.max_message_size == 0 {
            return Err(OdinError::Configuration("Max message size must be greater than 0".to_string()));
        }
        
        Ok(())
    }
}

/// Builder for OdinConfig
#[derive(Debug, Default)]
pub struct OdinConfigBuilder {
    node_id: Option<String>,
    network_endpoint: Option<String>,
    token: Option<String>,
    timeout: Option<Duration>,
    max_connections: Option<usize>,
    heartbeat_interval: Option<Duration>,
    max_retries: Option<u32>,
    debug: Option<bool>,
    performance_monitoring: Option<bool>,
    max_message_size: Option<usize>,
    buffer_size: Option<usize>,
}

impl OdinConfigBuilder {
    /// Create a new builder
    pub fn new() -> Self {
        Self::default()
    }
    
    /// Set the node ID
    pub fn node_id<S: Into<String>>(mut self, node_id: S) -> Self {
        self.node_id = Some(node_id.into());
        self
    }
    
    /// Set the network endpoint
    pub fn network_endpoint<S: Into<String>>(mut self, endpoint: S) -> Self {
        self.network_endpoint = Some(endpoint.into());
        self
    }
    
    /// Set the authentication token
    pub fn token<S: Into<String>>(mut self, token: S) -> Self {
        self.token = Some(token.into());
        self
    }
    
    /// Set the connection timeout
    pub fn timeout(mut self, timeout: Duration) -> Self {
        self.timeout = Some(timeout);
        self
    }
    
    /// Set the maximum number of connections
    pub fn max_connections(mut self, max_connections: usize) -> Self {
        self.max_connections = Some(max_connections);
        self
    }
    
    /// Set the heartbeat interval
    pub fn heartbeat_interval(mut self, interval: Duration) -> Self {
        self.heartbeat_interval = Some(interval);
        self
    }
    
    /// Set the maximum retry attempts
    pub fn max_retries(mut self, max_retries: u32) -> Self {
        self.max_retries = Some(max_retries);
        self
    }
    
    /// Enable or disable debug logging
    pub fn debug(mut self, debug: bool) -> Self {
        self.debug = Some(debug);
        self
    }
    
    /// Enable or disable performance monitoring
    pub fn performance_monitoring(mut self, enabled: bool) -> Self {
        self.performance_monitoring = Some(enabled);
        self
    }
    
    /// Set the maximum message size
    pub fn max_message_size(mut self, size: usize) -> Self {
        self.max_message_size = Some(size);
        self
    }
    
    /// Set the buffer size
    pub fn buffer_size(mut self, size: usize) -> Self {
        self.buffer_size = Some(size);
        self
    }
    
    /// Build the configuration
    pub fn build(self) -> Result<OdinConfig> {
        let mut config = OdinConfig::default();
        
        if let Some(node_id) = self.node_id {
            config.node_id = node_id;
        }
        
        if let Some(endpoint) = self.network_endpoint {
            config.network_endpoint = endpoint;
        }
        
        config.token = self.token;
        
        if let Some(timeout) = self.timeout {
            config.timeout = timeout;
        }
        
        if let Some(max_connections) = self.max_connections {
            config.max_connections = max_connections;
        }
        
        if let Some(interval) = self.heartbeat_interval {
            config.heartbeat_interval = interval;
        }
        
        if let Some(max_retries) = self.max_retries {
            config.max_retries = max_retries;
        }
        
        if let Some(debug) = self.debug {
            config.debug = debug;
        }
        
        if let Some(monitoring) = self.performance_monitoring {
            config.performance_monitoring = monitoring;
        }
        
        if let Some(size) = self.max_message_size {
            config.max_message_size = size;
        }
        
        if let Some(size) = self.buffer_size {
            config.buffer_size = size;
        }
        
        config.validate()?;
        Ok(config)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::time::Duration;
    
    #[test]
    fn test_default_config() {
        let config = OdinConfig::default();
        assert!(!config.node_id.is_empty());
        assert_eq!(config.network_endpoint, "ws://localhost:8080");
        assert!(!config.debug);
        assert!(config.performance_monitoring);
    }
    
    #[test]
    fn test_config_builder() {
        let config = OdinConfig::builder()
            .node_id("test-node")
            .network_endpoint("wss://example.com:9000")
            .timeout(Duration::from_secs(60))
            .max_connections(200)
            .debug(true)
            .build()
            .unwrap();
            
        assert_eq!(config.node_id, "test-node");
        assert_eq!(config.network_endpoint, "wss://example.com:9000");
        assert_eq!(config.timeout, Duration::from_secs(60));
        assert_eq!(config.max_connections, 200);
        assert!(config.debug);
    }
    
    #[test]
    fn test_config_validation() {
        let result = OdinConfig::builder()
            .node_id("")
            .build();
            
        assert!(result.is_err());
        assert!(matches!(result.unwrap_err(), OdinError::Configuration(_)));
    }
}