batata-client 0.0.2

Rust client for Batata/Nacos service discovery and configuration management
Documentation
use thiserror::Error;

/// Result type alias for batata client operations
pub type Result<T> = std::result::Result<T, BatataError>;

/// Error types for Batata client operations
#[derive(Error, Debug)]
pub enum BatataError {
    /// Configuration not found
    #[error("Config not found: dataId={data_id}, group={group}, namespace={namespace}")]
    ConfigNotFound {
        data_id: String,
        group: String,
        namespace: String,
    },

    /// Service not found
    #[error("Service not found: service={service_name}, group={group_name}, namespace={namespace}")]
    ServiceNotFound {
        service_name: String,
        group_name: String,
        namespace: String,
    },

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

    /// Server error with error code
    #[error("Server error: code={error_code}, message={message}")]
    ServerError { error_code: i32, message: String },

    /// Authentication error
    #[error("Authentication error: {message}")]
    AuthError { message: String },

    /// Permission denied
    #[error("Permission denied: {message}")]
    PermissionDenied { message: String },

    /// Request timeout
    #[error("Request timeout after {timeout_ms}ms")]
    Timeout { timeout_ms: u64 },

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

    /// gRPC transport error
    #[error("gRPC transport error: {0}")]
    TransportError(#[from] tonic::transport::Error),

    /// gRPC status error
    #[error("gRPC status error: {0}")]
    GrpcStatus(#[from] tonic::Status),

    /// Invalid parameter
    #[error("Invalid parameter: {0}")]
    InvalidParameter(String),

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

    /// No available server
    #[error("No available server")]
    NoAvailableServer,

    /// Client not started
    #[error("Client not started")]
    ClientNotStarted,

    /// Client already started
    #[error("Client already started")]
    ClientAlreadyStarted,

    /// Encryption/Decryption error
    #[error("Encryption error: {message}")]
    EncryptionError { message: String },
}

impl BatataError {
    /// Check if the error is retryable
    pub fn is_retryable(&self) -> bool {
        matches!(
            self,
            BatataError::ConnectionError { .. }
                | BatataError::Timeout { .. }
                | BatataError::TransportError(_)
                | BatataError::NoAvailableServer
        )
    }

    /// Create a server error from error code and message
    pub fn server_error(error_code: i32, message: impl Into<String>) -> Self {
        BatataError::ServerError {
            error_code,
            message: message.into(),
        }
    }

    /// Create a connection error
    pub fn connection_error(message: impl Into<String>) -> Self {
        BatataError::ConnectionError {
            message: message.into(),
        }
    }
}