use std::sync::Arc;
use http::{HeaderValue, header::AUTHORIZATION};
use reqwest::IntoUrl;
use crate::{Authorizer, error::Result};
#[derive(Debug, Clone)]
pub struct HttpClient<A: Authorizer> {
authorizer: A,
client: reqwest::Client,
}
impl<A: Authorizer> HttpClient<A> {
pub fn new(authorizer: A) -> Self {
Self {
authorizer,
client: reqwest::Client::new(),
}
}
#[must_use]
pub fn set_client(mut self, client: reqwest::Client) -> Self {
self.client = client;
self
}
pub fn authorization_header(&self) -> Result<Arc<HeaderValue>> {
self.authorizer.authorization_header()
}
pub fn request<U: IntoUrl>(
&self,
method: reqwest::Method,
url: U,
) -> Result<reqwest::RequestBuilder> {
let header = self.authorization_header()?;
let request = self
.client
.request(method, url)
.header(AUTHORIZATION, Arc::unwrap_or_clone(header));
Ok(request)
}
pub async fn execute(&self, mut request: reqwest::Request) -> Result<reqwest::Response> {
let header = self.authorization_header()?;
if !request.headers().contains_key(AUTHORIZATION) {
request
.headers_mut()
.insert(AUTHORIZATION, Arc::unwrap_or_clone(header));
}
self.client
.execute(request)
.await
.map_err(Arc::new)
.map_err(Into::into)
}
pub fn get<U: IntoUrl>(&self, url: U) -> Result<reqwest::RequestBuilder> {
self.request(reqwest::Method::GET, url)
}
pub fn post<U: IntoUrl>(&self, url: U) -> Result<reqwest::RequestBuilder> {
self.request(reqwest::Method::POST, url)
}
pub fn put<U: IntoUrl>(&self, url: U) -> Result<reqwest::RequestBuilder> {
self.request(reqwest::Method::PUT, url)
}
pub fn patch<U: IntoUrl>(&self, url: U) -> Result<reqwest::RequestBuilder> {
self.request(reqwest::Method::PATCH, url)
}
pub fn delete<U: IntoUrl>(&self, url: U) -> Result<reqwest::RequestBuilder> {
self.request(reqwest::Method::DELETE, url)
}
pub fn head<U: IntoUrl>(&self, url: U) -> Result<reqwest::RequestBuilder> {
self.request(reqwest::Method::HEAD, url)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::authorizers::BearerTokenAuthorizer;
#[tokio::test]
async fn test_http_client() {
let authorizer = BearerTokenAuthorizer::new("test").unwrap();
let client = HttpClient::new(authorizer);
let response = client
.get("https://httpbin.org/get")
.unwrap()
.send()
.await
.unwrap();
assert!(response.status().is_success());
}
}