bunny-api 0.0.5

Alpha API client for Bunny.net
Documentation
use std::ops::Deref;

use reqwest::{header::{HeaderMap, HeaderValue, InvalidHeaderValue}, Request, Response};

/// Errors that may occur when creating a new [`Client`].
#[derive(Debug, thiserror::Error)]
#[allow(clippy::module_name_repetitions)]
pub enum ClientError {
    /// The provided access key is not a valid header value.
    #[error("failed to set access key header: {0}")]
    AccessKey(#[from] InvalidHeaderValue),
    /// Failed to build the [`Client`] for some reason.
    #[error("failed to build client: {0}")]
    BuildClient(#[from] reqwest::Error),
}

/// API Client initialized with an API access key.
#[derive(Debug)]
pub struct Client(reqwest::Client);

impl Client {
    /// Create a new `Client` using the given access key.
    ///
    /// The client is configured to always use HTTPS.
    ///
    /// # Errors
    ///
    /// See [`ClientError`].
    pub fn new(access_key: &str) -> Result<Self, ClientError> {
        let access_key = HeaderValue::from_str(access_key)?;
        let mut headers = HeaderMap::with_capacity(1);
        headers.insert("AccessKey", access_key);
        let inner = reqwest::Client::builder()
            .default_headers(headers)
            .https_only(true)
            .build()?;
        Ok(Self(inner))
    }

    pub(crate) async fn send_logged(&self, req: Request) -> Result<Response, reqwest::Error> {
        #[cfg(feature = "tracing")]
        tracing::debug!(
            method=%req.method(),
            url=%req.url(),
            headers=?req.headers(),
            "about to send request",
        );

        self.execute(req).await
    }
}

impl Deref for Client {
    type Target = reqwest::Client;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}