revoke-core 0.3.0

Core traits and types for the Revoke microservices framework
Documentation
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use thiserror::Error;
use uuid::Uuid;

#[derive(Error, Debug)]
pub enum RevokeError {
    #[error("Service not found: {0}")]
    ServiceNotFound(String),

    #[error("Configuration error: {0}")]
    ConfigError(String),

    #[error("Connection error: {0}")]
    ConnectionError(String),

    #[error("Serialization error: {0}")]
    SerializationError(#[from] serde_json::Error),

    #[error("IO error: {0}")]
    IoError(#[from] std::io::Error),

    #[error("Unknown error: {0}")]
    Unknown(String),
}

pub type Result<T> = std::result::Result<T, RevokeError>;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceInfo {
    pub id: Uuid,
    pub name: String,
    pub version: String,
    pub address: String,
    pub port: u16,
    pub protocol: Protocol,
    pub metadata: HashMap<String, String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Protocol {
    Http,
    Https,
    Grpc,
    Tcp,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthStatus {
    pub service_id: Uuid,
    pub status: Status,
    pub last_check: chrono::DateTime<chrono::Utc>,
    pub message: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Status {
    Healthy,
    Unhealthy,
    Unknown,
}

#[async_trait]
pub trait ServiceRegistry: Send + Sync {
    async fn register(&self, service: ServiceInfo) -> Result<()>;
    async fn deregister(&self, service_id: Uuid) -> Result<()>;
    async fn get_service(&self, name: &str) -> Result<Vec<ServiceInfo>>;
    async fn update_health(&self, status: HealthStatus) -> Result<()>;
}

#[async_trait]
pub trait ConfigProvider: Send + Sync {
    async fn get(&self, key: &str) -> Result<String>;
    async fn set(&self, key: &str, value: &str) -> Result<()>;
    async fn watch(&self, key: &str) -> Result<Box<dyn futures::Stream<Item = String> + Send + Unpin>>;
}

#[async_trait]
pub trait MessageQueue: Send + Sync {
    async fn publish(&self, topic: &str, message: &[u8]) -> Result<()>;
    async fn subscribe(
        &self,
        topic: &str,
    ) -> Result<Box<dyn futures::Stream<Item = Vec<u8>> + Send + Unpin>>;
}

#[derive(Debug, Clone)]
pub struct ServiceContext {
    pub service_info: ServiceInfo,
    pub config: HashMap<String, String>,
}

pub mod middleware {
    use std::time::Duration;

    #[derive(Debug, Clone)]
    pub struct RetryConfig {
        pub max_attempts: u32,
        pub initial_delay: Duration,
        pub max_delay: Duration,
        pub multiplier: f32,
    }

    impl Default for RetryConfig {
        fn default() -> Self {
            Self {
                max_attempts: 3,
                initial_delay: Duration::from_millis(100),
                max_delay: Duration::from_secs(10),
                multiplier: 2.0,
            }
        }
    }

    #[derive(Debug, Clone)]
    pub struct CircuitBreakerConfig {
        pub failure_threshold: u32,
        pub success_threshold: u32,
        pub timeout: Duration,
    }

    impl Default for CircuitBreakerConfig {
        fn default() -> Self {
            Self {
                failure_threshold: 5,
                success_threshold: 2,
                timeout: Duration::from_secs(60),
            }
        }
    }
}