clicksend-rs 0.1.1

Unofficial ClickSend SDK for Rust (async + optional blocking).
Documentation
//! Error type returned by every API call.

use thiserror::Error;

/// Anything that can go wrong talking to ClickSend.
#[derive(Debug, Error)]
pub enum ClickSendError {
    /// Underlying transport error (DNS, TLS, connection, decode body).
    #[error("http error: {0}")]
    Http(#[from] reqwest::Error),

    /// HTTP 401 — bad username or api_key.
    #[error("unauthorized — bad username or api key")]
    Unauthorized,

    /// HTTP 404 — resource missing. Body included for debugging.
    #[error("not found: {0}")]
    NotFound(String),

    /// Non-success HTTP status (4xx/5xx) that is not 401/404/429.
    /// Use [`ClickSendError::Api`] for the case where ClickSend returns
    /// HTTP 200 but an error envelope.
    #[error("api error ({code}): {message}")]
    Http4xx5xx {
        /// HTTP status code.
        code: u16,
        /// Raw response body.
        message: String,
    },

    /// HTTP 200 with `response_code != "SUCCESS"`. ClickSend returns
    /// logical errors this way (bad sender id, blocked country, throttled, …).
    #[error("api error: {code} — {message}")]
    Api {
        /// ClickSend `response_code` (e.g. `"ERROR"`, `"INVALID_FROM"`).
        code: String,
        /// ClickSend `response_msg`.
        message: String,
        /// Raw envelope body for debugging.
        body: String,
    },

    /// JSON decode failed. Includes the offending body so you can file a bug.
    #[error("decode error: {message}\nbody: {body}")]
    Decode {
        /// `serde_json` error message.
        message: String,
        /// Raw body that failed to decode.
        body: String,
    },

    /// HTTP 429 after retries are exhausted.
    #[error("rate limited (retry-after: {retry_after_secs:?}s)")]
    RateLimited {
        /// `Retry-After` header value, if present.
        retry_after_secs: Option<u64>,
    },

    /// Builder rejected something — empty creds, etc.
    #[error("invalid config: {0}")]
    InvalidConfig(String),
}