hetzner 1.0.0

A Rust library for managing DNS records and zones on Hetzner's platform, providing tools for networking and DNS management.
Documentation
use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::fmt;

#[derive(Debug)]
pub enum HetznerError {
    Http(reqwest::Error),
    Serialization(serde_json::Error),
    Api(ApiError),
    UnexpectedResponse(&'static str),
}

impl fmt::Display for HetznerError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Http(err) => write!(f, "http request failed: {err}"),
            Self::Serialization(err) => write!(f, "failed to decode response body: {err}"),
            Self::Api(err) => write!(
                f,
                "api error (status {}, code {}): {}",
                err.status.as_u16(),
                err.code,
                err.message
            ),
            Self::UnexpectedResponse(message) => write!(f, "unexpected response: {message}"),
        }
    }
}

impl std::error::Error for HetznerError {}

impl From<reqwest::Error> for HetznerError {
    fn from(value: reqwest::Error) -> Self {
        Self::Http(value)
    }
}

impl From<serde_json::Error> for HetznerError {
    fn from(value: serde_json::Error) -> Self {
        Self::Serialization(value)
    }
}

#[derive(Debug, Clone)]
pub struct ApiError {
    pub status: StatusCode,
    pub code: String,
    pub message: String,
    pub details: Option<Value>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ApiErrorEnvelope {
    pub error: ApiErrorBody,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ApiErrorBody {
    pub code: String,
    pub message: String,
    #[serde(default)]
    pub details: Option<Value>,
}

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