keplars 2.1.0

Official Rust SDK for Keplars Email API
Documentation
use thiserror::Error;

#[derive(Debug, Error)]
pub enum KeplarsError {
    #[error("Validation error: {message}")]
    Validation {
        message: String,
        status_code: u16,
    },

    #[error("Authentication error: {message}")]
    Authentication {
        message: String,
        status_code: u16,
    },

    #[error("Authorization error: {message}")]
    Authorization {
        message: String,
        status_code: u16,
    },

    #[error("Domain not verified: {message}")]
    DomainNotVerified {
        message: String,
        status_code: u16,
    },

    #[error("Rate limit exceeded: {message}")]
    RateLimit {
        message: String,
        retry_after: u64,
        status_code: u16,
    },

    #[error("Not found: {message}")]
    NotFound {
        message: String,
        status_code: u16,
    },

    #[error("Conflict: {message}")]
    Conflict {
        message: String,
        status_code: u16,
    },

    #[error("Internal error: {message}")]
    Internal {
        message: String,
        status_code: u16,
    },

    #[error("Network error: {0}")]
    Network(#[from] reqwest::Error),

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

    #[error("{message}")]
    Api {
        message: String,
        status_code: u16,
    },
}

impl KeplarsError {
    pub fn status_code(&self) -> Option<u16> {
        match self {
            Self::Validation { status_code, .. } => Some(*status_code),
            Self::Authentication { status_code, .. } => Some(*status_code),
            Self::Authorization { status_code, .. } => Some(*status_code),
            Self::DomainNotVerified { status_code, .. } => Some(*status_code),
            Self::RateLimit { status_code, .. } => Some(*status_code),
            Self::NotFound { status_code, .. } => Some(*status_code),
            Self::Conflict { status_code, .. } => Some(*status_code),
            Self::Internal { status_code, .. } => Some(*status_code),
            Self::Api { status_code, .. } => Some(*status_code),
            _ => None,
        }
    }

    pub fn from_status(status: u16, message: String) -> Self {
        match status {
            400 => Self::Validation { message, status_code: 400 },
            401 => Self::Authentication { message, status_code: 401 },
            403 => Self::Authorization { message, status_code: 403 },
            404 => Self::NotFound { message, status_code: 404 },
            409 => Self::Conflict { message, status_code: 409 },
            429 => Self::RateLimit { message, retry_after: 60, status_code: 429 },
            500 | 502 | 503 => Self::Internal { message, status_code: status },
            _ => Self::Api { message, status_code: status },
        }
    }
}

pub type KeplarsResult<T> = Result<T, KeplarsError>;