openapi-nexus 0.1.6

OpenAPI 3.x multi-language code generator
Documentation
use std::fmt;
use std::sync::Arc;

use crate::runtime::auth::Authenticator;

/// Synchronous HTTP client wrapping `ureq::Agent`.
pub struct Client {
    inner: ureq::Agent,
    base_url: String,
    authenticator: Option<Arc<dyn Authenticator>>,
}

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

    /// Create a client with a custom `ureq::Agent`.
    pub fn with_agent(inner: ureq::Agent, 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>) -> Self {
        self.authenticator = Some(auth);
        self
    }

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

    fn apply_auth<S>(&self, mut req: ureq::RequestBuilder<S>) -> ureq::RequestBuilder<S> {
        if let Some(auth) = &self.authenticator {
            for (key, value) in auth.auth_headers() {
                req = req.header(key, &value);
            }
        }
        req
    }

    /// Build a GET request.
    pub fn get(&self, path: &str) -> ureq::RequestBuilder<ureq::typestate::WithoutBody> {
        self.apply_auth(self.inner.get(&self.full_url(path)))
    }

    /// Build a POST request.
    pub fn post(&self, path: &str) -> ureq::RequestBuilder<ureq::typestate::WithBody> {
        self.apply_auth(self.inner.post(&self.full_url(path)))
    }

    /// Build a PUT request.
    pub fn put(&self, path: &str) -> ureq::RequestBuilder<ureq::typestate::WithBody> {
        self.apply_auth(self.inner.put(&self.full_url(path)))
    }

    /// Build a DELETE request.
    pub fn delete(&self, path: &str) -> ureq::RequestBuilder<ureq::typestate::WithoutBody> {
        self.apply_auth(self.inner.delete(&self.full_url(path)))
    }

    /// Build a PATCH request.
    pub fn patch(&self, path: &str) -> ureq::RequestBuilder<ureq::typestate::WithBody> {
        self.apply_auth(self.inner.patch(&self.full_url(path)))
    }

    /// Build a HEAD request.
    pub fn head(&self, path: &str) -> ureq::RequestBuilder<ureq::typestate::WithoutBody> {
        self.apply_auth(self.inner.head(&self.full_url(path)))
    }
}

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