pub use crate::client_trait_common::{HttpRequest, TeamSelect};
use crate::Error;
use bytes::Bytes;
use futures::AsyncRead;
use std::future::{ready, Future};
use std::sync::Arc;
pub trait HttpClient: Sync {
type Request: HttpRequest + Send;
fn execute(
&self,
request: Self::Request,
body: Bytes,
) -> impl Future<Output = Result<HttpRequestResultRaw, Error>> + Send;
fn new_request(&self, url: &str) -> Self::Request;
fn update_token(
&self,
_old_token: Arc<String>,
) -> impl Future<Output = Result<bool, Error>> + Send {
ready(Ok(false))
}
fn token(&self) -> Option<Arc<String>> {
None
}
fn path_root(&self) -> Option<&str> {
None
}
fn team_select(&self) -> Option<&TeamSelect> {
None
}
#[doc(hidden)]
#[cfg(feature = "sync_routes")]
fn execute_borrowed_body(
&self,
_request: Self::Request,
_body_slice: &[u8],
) -> impl Future<Output = Result<HttpRequestResultRaw, Error>> + Send {
unimplemented!();
#[allow(unreachable_code)] async move {
unimplemented!()
}
}
}
pub struct HttpRequestResultRaw {
pub status: u16,
pub result_header: Option<String>,
pub content_length: Option<u64>,
pub body: Box<dyn AsyncRead + Send + Unpin>,
}
pub struct HttpRequestResult<T> {
pub result: T,
pub content_length: Option<u64>,
pub body: Option<Box<dyn AsyncRead + Unpin + Send>>,
}
#[cfg(feature = "sync_routes")]
impl<T: crate::client_trait::HttpClient + Sync> HttpClient for T {
type Request = T::Request;
async fn execute(
&self,
request: Self::Request,
body: Bytes,
) -> Result<HttpRequestResultRaw, Error> {
self.execute_borrowed_body(request, &body).await
}
async fn execute_borrowed_body(
&self,
request: Self::Request,
body_slice: &[u8],
) -> Result<HttpRequestResultRaw, Error> {
self.execute(request, body_slice)
.map(|r| HttpRequestResultRaw {
status: r.status,
result_header: r.result_header,
content_length: r.content_length,
body: Box::new(SyncReadAdapter { inner: r.body }),
})
}
fn new_request(&self, url: &str) -> Self::Request {
self.new_request(url)
}
fn update_token(
&self,
old_token: Arc<String>,
) -> impl Future<Output = Result<bool, Error>> + Send {
ready(self.update_token(old_token))
}
fn token(&self) -> Option<Arc<String>> {
self.token()
}
fn path_root(&self) -> Option<&str> {
self.path_root()
}
fn team_select(&self) -> Option<&TeamSelect> {
self.team_select()
}
}
pub trait NoauthClient: HttpClient {}
pub trait UserAuthClient: HttpClient {}
pub trait TeamAuthClient: HttpClient {}
pub trait AppAuthClient: HttpClient {}
#[cfg(feature = "sync_routes")]
impl<T: crate::client_trait::NoauthClient + Sync> NoauthClient for T {}
#[cfg(feature = "sync_routes")]
impl<T: crate::client_trait::UserAuthClient + Sync> UserAuthClient for T {}
#[cfg(feature = "sync_routes")]
impl<T: crate::client_trait::TeamAuthClient + Sync> TeamAuthClient for T {}
#[cfg(feature = "sync_routes")]
impl<T: crate::client_trait::AppAuthClient + Sync> AppAuthClient for T {}
#[cfg(feature = "sync_routes")]
pub(crate) struct SyncReadAdapter {
pub inner: Box<dyn std::io::Read + Send>,
}
#[cfg(feature = "sync_routes")]
impl AsyncRead for SyncReadAdapter {
fn poll_read(
mut self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
buf: &mut [u8],
) -> std::task::Poll<std::io::Result<usize>> {
std::task::Poll::Ready(std::io::Read::read(&mut self.inner, buf))
}
fn poll_read_vectored(
mut self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
bufs: &mut [std::io::IoSliceMut<'_>],
) -> std::task::Poll<std::io::Result<usize>> {
std::task::Poll::Ready(std::io::Read::read_vectored(&mut self.inner, bufs))
}
}