openapi-nexus 0.1.0

OpenAPI 3.1 to code generator
Documentation
use std::fmt;
use std::sync::Arc;

use aioduct::Runtime;

use crate::runtime::auth::Authenticator;
use crate::runtime::error::Error;

/// Async HTTP client wrapping `aioduct::Client<R>`.
pub struct Client<R: Runtime> {
    inner: aioduct::Client<R>,
    base_url: String,
    authenticator: Option<Arc<dyn Authenticator<R>>>,
}

impl<R: Runtime> Client<R> {
    /// Create a new client with the given base URL.
    pub fn new(base_url: &str) -> Self {
        Self {
            inner: aioduct::Client::<R>::new(),
            base_url: base_url.trim_end_matches('/').to_string(),
            authenticator: None,
        }
    }

    /// Create a client with a custom `aioduct::Client`.
    pub fn with_client(inner: aioduct::Client<R>, base_url: &str) -> Self {
        Self {
            inner,
            base_url: base_url.trim_end_matches('/').to_string(),
            authenticator: None,
        }
    }

    /// Attach an authenticator to the client.
    pub fn with_auth(mut self, auth: Arc<dyn Authenticator<R>>) -> Self {
        self.authenticator = Some(auth);
        self
    }

    fn full_url(&self, path: &str) -> String {
        format!("{}{}", self.base_url, path)
    }

    /// Build a GET request.
    pub fn get(&self, path: &str) -> Result<aioduct::RequestBuilder<'_, R>, Error> {
        let mut req = self.inner.get(&self.full_url(path))?;
        if let Some(auth) = &self.authenticator {
            req = auth.authenticate(req)?;
        }
        Ok(req)
    }

    /// Build a POST request.
    pub fn post(&self, path: &str) -> Result<aioduct::RequestBuilder<'_, R>, Error> {
        let mut req = self.inner.post(&self.full_url(path))?;
        if let Some(auth) = &self.authenticator {
            req = auth.authenticate(req)?;
        }
        Ok(req)
    }

    /// Build a PUT request.
    pub fn put(&self, path: &str) -> Result<aioduct::RequestBuilder<'_, R>, Error> {
        let mut req = self.inner.put(&self.full_url(path))?;
        if let Some(auth) = &self.authenticator {
            req = auth.authenticate(req)?;
        }
        Ok(req)
    }

    /// Build a DELETE request.
    pub fn delete(&self, path: &str) -> Result<aioduct::RequestBuilder<'_, R>, Error> {
        let mut req = self.inner.delete(&self.full_url(path))?;
        if let Some(auth) = &self.authenticator {
            req = auth.authenticate(req)?;
        }
        Ok(req)
    }

    /// Build a PATCH request.
    pub fn patch(&self, path: &str) -> Result<aioduct::RequestBuilder<'_, R>, Error> {
        let mut req = self.inner.patch(&self.full_url(path))?;
        if let Some(auth) = &self.authenticator {
            req = auth.authenticate(req)?;
        }
        Ok(req)
    }

    /// Build a HEAD request.
    pub fn head(&self, path: &str) -> Result<aioduct::RequestBuilder<'_, R>, Error> {
        let mut req = self.inner.head(&self.full_url(path))?;
        if let Some(auth) = &self.authenticator {
            req = auth.authenticate(req)?;
        }
        Ok(req)
    }
}

impl<R: Runtime> fmt::Debug for Client<R> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Client")
            .field("base_url", &self.base_url)
            .finish()
    }
}