opentalk-client 0.0.1

A client library to interact with OpenTalk
Documentation
// SPDX-FileCopyrightText: OpenTalk GmbH <mail@opentalk.eu>
//
// SPDX-License-Identifier: EUPL-1.2

use std::{future::Future, ops::Deref, pin::Pin};

use oauth2::{AsyncHttpClient, HttpClientError, HttpRequest, HttpResponse, http};

/// This is a temporary solution to use openidconnect with reqwest 0.13 until upstream provides
/// support for it themselves.
///
/// Circumvents the orphan rule in AsyncHTTPClient implementations
#[derive(Debug, Clone)]
pub struct ClientWrapper(pub reqwest::Client);

impl<'c> AsyncHttpClient<'c> for ClientWrapper {
    type Error = HttpClientError<reqwest::Error>;

    #[cfg(target_arch = "wasm32")]
    type Future = Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + 'c>>;
    #[cfg(not(target_arch = "wasm32"))]
    type Future =
        Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + Send + Sync + 'c>>;

    fn call(&'c self, request: HttpRequest) -> Self::Future {
        Box::pin(async move {
            let response = self
                .0
                .execute(request.try_into().map_err(Box::new)?)
                .await
                .map_err(Box::new)?;

            let mut builder = http::Response::builder().status(response.status());

            #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
            {
                builder = builder.version(response.version());
            }

            for (name, value) in response.headers().iter() {
                builder = builder.header(name, value);
            }

            let bytes = response.bytes().await.map_err(Box::new)?.to_vec();

            builder.body(bytes).map_err(HttpClientError::Http)
        })
    }
}

impl From<reqwest::Client> for ClientWrapper {
    fn from(value: reqwest::Client) -> Self {
        Self(value)
    }
}

impl From<&reqwest::Client> for ClientWrapper {
    fn from(value: &reqwest::Client) -> Self {
        Self(value.clone())
    }
}

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

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