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
//! Examples for the ODIN Protocol Rust crate

use odin_protocol::{
    OdinProtocol, OdinConfig, HELRuleEngine, Rule, Condition, Action, LogLevel,
    MessagePriority, MessageType, OdinMessage, MetricsCollector,
    Result,
};
use std::time::Duration;
use tokio::time::sleep;

/// Basic usage example
#[tokio::main]
async fn main() -> Result<()> {
    println!("🚀 ODIN Protocol Rust Examples");
    println!("===============================\n");

    // Example 1: Basic Protocol Usage
    println!("📡 Example 1: Basic Protocol Usage");
    basic_protocol_example().await?;
    
    println!("\n{}\n", "=".repeat(50));
    
    // Example 2: HEL Rule Engine
    println!("🧠 Example 2: HEL Rule Engine");
    hel_rule_engine_example().await?;
    
    println!("\n{}\n", "=".repeat(50));
    
    // Example 3: Performance Monitoring
    println!("📊 Example 3: Performance Monitoring");
    performance_monitoring_example().await?;
    
    println!("\n{}\n", "=".repeat(50));
    
    // Example 4: Message Filtering
    println!("🔍 Example 4: Message Filtering");
    message_filtering_example().await?;
    
    println!("\n✅ All examples completed successfully!");
    Ok(())
}

/// Basic protocol usage demonstration
async fn basic_protocol_example() -> Result<()> {
    // Create configuration
    let config = OdinConfig::builder()
        .node_id("rust-example-node")
        .network_endpoint("ws://localhost:8080")
        .max_connections(50)
        .debug(true)
        .build()?;
    
    // Initialize protocol
    let mut protocol = OdinProtocol::new(config)?;
    
    println!("  ✓ Created ODIN Protocol instance");
    
    // Start the protocol
    protocol.start().await?;
    println!("  ✓ Protocol started successfully");
    
    // Subscribe to messages
    let mut message_rx = protocol.subscribe_to_messages();
    
    // Send a message
    let message_id = protocol.send_message(
        "ai-coordinator",
        "Hello from Rust ODIN Protocol!",
        MessagePriority::Normal
    ).await?;
    
    println!("  ✓ Message sent with ID: {}", message_id);
    
    // Broadcast a message
    let broadcast_id = protocol.broadcast_message(
        "System startup complete - Rust node ready",
        MessagePriority::High
    ).await?;
    
    println!("  ✓ Broadcast sent with ID: {}", broadcast_id);
    
    // Listen for a message (with timeout)
    match tokio::time::timeout(Duration::from_millis(100), message_rx.recv()).await {
        Ok(Ok(message)) => {
            println!("  ✓ Received message: {}", message.content);
        }
        _ => {
            println!("  ℹ No messages received (expected in example)");
        }
    }
    
    // Get status
    let status = protocol.get_status();
    println!("  ✓ Node status: {} connections, uptime: {:.2}s", 
             status.connection_count, status.uptime);
    
    // Stop the protocol
    protocol.stop().await?;
    println!("  ✓ Protocol stopped gracefully");
    
    Ok(())
}

/// HEL Rule Engine demonstration
async fn hel_rule_engine_example() -> Result<()> {
    let engine = HELRuleEngine::new();
    println!("  ✓ Created HEL Rule Engine");
    
    // Create a greeting rule
    let greeting_rule = Rule::new(
        "greeting-response".to_string(),
        "Greeting Response Rule".to_string(),
        "Automatically responds to greetings".to_string(),
    )
    .priority(10)
    .add_condition(Condition::ContentContains("hello".to_string()))
    .add_condition(Condition::PriorityEquals(MessagePriority::Normal))
    .add_action(Action::Log {
        level: LogLevel::Info,
        message: "Greeting detected - sending automated response".to_string(),
    });
    
    engine.add_rule(greeting_rule).await?;
    println!("  ✓ Added greeting response rule");
    
    // Create an urgent message rule
    let urgent_rule = Rule::new(
        "urgent-handler".to_string(),
        "Urgent Message Handler".to_string(),
        "Handles urgent priority messages".to_string(),
    )
    .priority(100)
    .add_condition(Condition::PriorityEquals(MessagePriority::Critical))
    .add_action(Action::Log {
        level: LogLevel::Warning,
        message: "URGENT MESSAGE RECEIVED - Escalating".to_string(),
    });
    
    engine.add_rule(urgent_rule).await?;
    println!("  ✓ Added urgent message handler rule");
    
    // Test rules with sample messages
    let test_messages = vec![
        OdinMessage::new(
            MessageType::Standard,
            "test-node",
            "rust-example-node",
            "hello there!",
            MessagePriority::Normal,
        ),
        OdinMessage::new(
            MessageType::Standard,
            "test-node",
            "rust-example-node",
            "SYSTEM ALERT: Critical failure detected",
            MessagePriority::Critical,
        ),
        OdinMessage::new(
            MessageType::Standard,
            "test-node",
            "rust-example-node",
            "regular message",
            MessagePriority::Low,
        ),
    ];
    
    for message in test_messages {
        let results = engine.execute_rules(&message).await?;
        println!("  ✓ Message '{}' triggered {} rules", 
                 message.content.chars().take(20).collect::<String>(), 
                 results.len());
        
        for result in results {
            if result.success {
                println!("    → Rule '{}' executed successfully in {:.2}ms", 
                         result.rule_id, result.execution_time.as_secs_f64() * 1000.0);
            } else {
                println!("    ✗ Rule '{}' failed: {}", 
                         result.rule_id, result.error.unwrap_or_default());
            }
        }
    }
    
    // Get rule statistics
    let stats = engine.get_stats().await;
    println!("  ✓ Rule engine stats: {} rules added, {} executed, {:.1}% success rate",
             stats.rules_added, stats.rules_executed, stats.success_rate() * 100.0);
    
    Ok(())
}

/// Performance monitoring demonstration
async fn performance_monitoring_example() -> Result<()> {
    let metrics = MetricsCollector::new();
    println!("  ✓ Created metrics collector");
    
    // Simulate some activity
    for i in 0..100 {
        metrics.record_message_sent();
        
        if i % 10 == 0 {
            metrics.record_message_received();
        }
        
        if i % 25 == 0 {
            metrics.record_error();
        }
        
        // Simulate processing time
        let processing_time = Duration::from_micros(50 + (i % 10) * 10);
        metrics.record_processing_time(processing_time);
        
        // Record sample
        metrics.record_sample(
            "message_processing".to_string(),
            processing_time,
            i % 25 != 0, // Fail every 25th operation
        ).await;
    }
    
    // Add some connections
    for _ in 0..5 {
        metrics.add_connection();
    }
    
    // Wait a moment for metrics to accumulate
    sleep(Duration::from_millis(10)).await;
    
    // Get basic metrics
    let basic_metrics = metrics.get_metrics();
    println!("  ✓ Basic metrics collected:");
    for (key, value) in &basic_metrics {
        println!("    {} = {:.2}", key, value);
    }
    
    // Get detailed performance stats
    let perf_stats = metrics.get_performance_stats().await;
    println!("  ✓ Performance statistics:");
    println!("    Total samples: {}", perf_stats.total_samples);
    println!("    Success rate: {:.1}%", perf_stats.success_rate * 100.0);
    println!("    Average duration: {:.2}ms", perf_stats.avg_duration_ms);
    println!("    95th percentile: {:.2}ms", perf_stats.p95_duration_ms);
    println!("    Messages/second: {:.0}", perf_stats.messages_per_second);
    
    // Export metrics in different formats
    let prometheus = odin_protocol::MetricsExporter::to_prometheus(&basic_metrics);
    println!("  ✓ Exported Prometheus format ({} chars)", prometheus.len());
    
    Ok(())
}

/// Message filtering demonstration
async fn message_filtering_example() -> Result<()> {
    use odin_protocol::MessageFilter;
    
    // Create test messages
    let messages = vec![
        OdinMessage::new(
            MessageType::Standard,
            "alice",
            "bob",
            "hello world",
            MessagePriority::Normal,
        ),
        OdinMessage::new(
            MessageType::Broadcast,
            "system",
            "all",
            "system announcement",
            MessagePriority::High,
        ),
        OdinMessage::new(
            MessageType::Error,
            "service",
            "admin",
            "error occurred",
            MessagePriority::Critical,
        ),
        OdinMessage::new(
            MessageType::Heartbeat,
            "node1",
            "all",
            "ping",
            MessagePriority::Low,
        ),
    ];
    
    println!("  ✓ Created {} test messages", messages.len());
    
    // Test different filters
    let filters = vec![
        ("High priority only", MessageFilter::new().with_min_priority(MessagePriority::High)),
        ("From 'alice'", MessageFilter::new().with_source("alice".to_string())),
        ("Broadcast messages", MessageFilter::new().with_type(MessageType::Broadcast)),
        ("Contains 'hello'", MessageFilter::new().with_content("hello".to_string())),
    ];
    
    for (description, filter) in filters {
        let matching = messages.iter().filter(|msg| filter.matches(msg)).count();
        println!("  ✓ Filter '{}': {} matches", description, matching);
    }
    
    // Create and test a message batch
    let mut batch = odin_protocol::MessageBatch::new();
    for message in messages {
        batch = batch.add_message(message);
    }
    
    println!("  ✓ Created message batch: {} messages, {} bytes", 
             batch.len(), batch.total_size());
    
    // Split batch into smaller batches
    let split_batches = batch.split(2);
    println!("  ✓ Split into {} smaller batches", split_batches.len());
    
    Ok(())
}

/// Helper function to demonstrate error handling
async fn _error_handling_example() -> Result<()> {
    // This function demonstrates proper error handling patterns
    // but is not called in the main example to avoid actual failures
    
    // Example of configuration error
    let result = OdinConfig::builder()
        .node_id("") // Empty node ID will cause validation error
        .build();
    
    match result {
        Ok(_) => println!("  Unexpected success"),
        Err(e) => {
            println!("  ✓ Caught configuration error: {}", e);
            println!("    Category: {}", e.category());
            println!("    Retryable: {}", e.is_retryable());
        }
    }
    
    Ok(())
}