use crate::{NoopResponseMiddleware, RequestBuilder, ResponseMiddleware};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct Client<MW = NoopResponseMiddleware> {
inner: reqwest::Client,
response_middleware: MW,
rate_limiter: Option<Arc<governor::DefaultDirectRateLimiter>>,
}
impl Client {
pub fn builder() -> ClientBuilder<NoopResponseMiddleware> {
ClientBuilder::new()
}
}
impl<MW> Client<MW>
where
MW: ResponseMiddleware + Clone,
{
pub fn get<U: reqwest::IntoUrl>(&self, url: U) -> RequestBuilder<MW> {
let inner = self.inner.get(url);
RequestBuilder::from_parts(self.clone(), inner)
}
pub fn post<U: reqwest::IntoUrl>(&self, url: U) -> RequestBuilder<MW> {
let inner = self.inner.post(url);
RequestBuilder::from_parts(self.clone(), inner)
}
pub fn put<U: reqwest::IntoUrl>(&self, url: U) -> RequestBuilder<MW> {
let inner = self.inner.put(url);
RequestBuilder::from_parts(self.clone(), inner)
}
pub fn patch<U: reqwest::IntoUrl>(&self, url: U) -> RequestBuilder<MW> {
let inner = self.inner.patch(url);
RequestBuilder::from_parts(self.clone(), inner)
}
pub fn delete<U: reqwest::IntoUrl>(&self, url: U) -> RequestBuilder<MW> {
let inner = self.inner.delete(url);
RequestBuilder::from_parts(self.clone(), inner)
}
pub fn head<U: reqwest::IntoUrl>(&self, url: U) -> RequestBuilder<MW> {
let inner = self.inner.head(url);
RequestBuilder::from_parts(self.clone(), inner)
}
pub fn request<U: reqwest::IntoUrl>(
&self,
method: reqwest::Method,
url: U,
) -> RequestBuilder<MW> {
let inner = self.inner.request(method, url);
RequestBuilder::from_parts(self.clone(), inner)
}
pub(crate) fn middleware(&self) -> &MW {
&self.response_middleware
}
pub(crate) fn rate_limiter(&self) -> Option<Arc<governor::DefaultDirectRateLimiter>> {
self.rate_limiter.clone()
}
}
pub struct ClientBuilder<MW> {
inner: reqwest::ClientBuilder,
response_middleware: MW,
rate_limiter: Option<Arc<governor::DefaultDirectRateLimiter>>,
}
impl Default for ClientBuilder<NoopResponseMiddleware> {
fn default() -> Self {
Self::new()
}
}
impl ClientBuilder<NoopResponseMiddleware> {
pub fn new() -> Self {
Self {
inner: reqwest::Client::builder(),
response_middleware: NoopResponseMiddleware,
rate_limiter: None,
}
}
}
impl<MW> ClientBuilder<MW>
where
MW: ResponseMiddleware + Clone,
{
pub fn from_reqwest_builder(inner: reqwest::ClientBuilder, response_middleware: MW) -> Self {
Self {
inner,
response_middleware,
rate_limiter: None,
}
}
pub fn configure<F>(self, f: F) -> Self
where
F: FnOnce(reqwest::ClientBuilder) -> reqwest::ClientBuilder,
{
Self {
inner: f(self.inner),
response_middleware: self.response_middleware,
rate_limiter: self.rate_limiter,
}
}
pub fn response_middleware<NewMW>(self, response_middleware: NewMW) -> ClientBuilder<NewMW>
where
NewMW: ResponseMiddleware + Clone,
{
ClientBuilder {
inner: self.inner,
response_middleware,
rate_limiter: self.rate_limiter,
}
}
pub fn rate_limiter(
self,
rate_limiter: Arc<governor::DefaultDirectRateLimiter>,
) -> ClientBuilder<MW> {
ClientBuilder {
inner: self.inner,
response_middleware: self.response_middleware,
rate_limiter: Some(rate_limiter),
}
}
pub fn user_agent<V>(self, value: V) -> Self
where
V: TryInto<reqwest::header::HeaderValue>,
V::Error: Into<http::Error>,
{
Self {
inner: self.inner.user_agent(value),
response_middleware: self.response_middleware,
rate_limiter: self.rate_limiter,
}
}
pub fn default_headers(self, headers: reqwest::header::HeaderMap) -> Self {
Self {
inner: self.inner.default_headers(headers),
response_middleware: self.response_middleware,
rate_limiter: self.rate_limiter,
}
}
pub fn timeout(self, timeout: std::time::Duration) -> Self {
Self {
inner: self.inner.timeout(timeout),
response_middleware: self.response_middleware,
rate_limiter: self.rate_limiter,
}
}
pub fn build(self) -> Result<Client<MW>, reqwest::Error> {
let inner = self.inner.build()?;
Ok(Client {
inner,
response_middleware: self.response_middleware,
rate_limiter: self.rate_limiter,
})
}
pub fn attach_client(self, client: reqwest::Client) -> Client<MW> {
Client {
inner: client,
response_middleware: self.response_middleware,
rate_limiter: self.rate_limiter,
}
}
}