dropbox_sdk/
async_client_trait.rs1use std::future::{Future, ready};
4use std::sync::Arc;
5use bytes::Bytes;
6use futures::AsyncRead;
7pub use crate::client_trait_common::{HttpRequest, TeamSelect};
8use crate::Error;
9
10pub trait HttpClient: Sync {
12    type Request: HttpRequest + Send;
14
15    fn execute(
17        &self,
18        request: Self::Request,
19        body: Bytes,
20    ) -> impl Future<Output = Result<HttpRequestResultRaw, Error>> + Send;
21
22    fn new_request(&self, url: &str) -> Self::Request;
24
25    fn update_token(
30        &self,
31        _old_token: Arc<String>,
32    ) -> impl Future<Output = Result<bool, Error>> + Send {
33        ready(Ok(false))
34    }
35
36    fn token(&self) -> Option<Arc<String>> {
38        None
39    }
40
41    fn path_root(&self) -> Option<&str> {
43        None
44    }
45
46    fn team_select(&self) -> Option<&TeamSelect> {
48        None
49    }
50
51    #[doc(hidden)]
64    #[cfg(feature = "sync_routes")]
65    fn execute_borrowed_body(
66        &self,
67        _request: Self::Request,
68        _body_slice: &[u8],
69    ) -> impl Future<Output = Result<HttpRequestResultRaw, Error>> + Send {
70        unimplemented!();
71        #[allow(unreachable_code)] async move { unimplemented!() }
73    }
74}
75
76pub struct HttpRequestResultRaw {
78    pub status: u16,
80
81    pub result_header: Option<String>,
83
84    pub content_length: Option<u64>,
86
87    pub body: Box<dyn AsyncRead + Send + Unpin>,
89}
90
91pub struct HttpRequestResult<T> {
94    pub result: T,
96
97    pub content_length: Option<u64>,
100
101    pub body: Option<Box<dyn AsyncRead + Unpin + Send>>,
104}
105
106#[cfg(feature = "sync_routes")]
110impl<T: crate::client_trait::HttpClient + Sync> HttpClient for T {
111    type Request = T::Request;
112
113    async fn execute(&self, request: Self::Request, body: Bytes)
114        -> Result<HttpRequestResultRaw, Error>
115    {
116        self.execute_borrowed_body(request, &body).await
117    }
118
119    async fn execute_borrowed_body(&self, request: Self::Request, body_slice: &[u8])
120        -> Result<HttpRequestResultRaw, Error>
121    {
122        self.execute(request, body_slice).map(|r| {
123            HttpRequestResultRaw {
124                status: r.status,
125                result_header: r.result_header,
126                content_length: r.content_length,
127                body: Box::new(SyncReadAdapter { inner: r.body }),
128            }
129        })
130    }
131
132    fn new_request(&self, url: &str) -> Self::Request {
133        self.new_request(url)
134    }
135
136    fn update_token(&self, old_token: Arc<String>)
137        -> impl Future<Output=Result<bool, Error>> + Send
138    {
139        ready(self.update_token(old_token))
140    }
141
142    fn token(&self) -> Option<Arc<String>> {
143        self.token()
144    }
145
146    fn path_root(&self) -> Option<&str> {
147        self.path_root()
148    }
149
150    fn team_select(&self) -> Option<&TeamSelect> {
151        self.team_select()
152    }
153}
154
155pub trait NoauthClient: HttpClient {}
157
158pub trait UserAuthClient: HttpClient {}
161
162pub trait TeamAuthClient: HttpClient {}
166
167pub trait AppAuthClient: HttpClient {}
171
172#[cfg(feature = "sync_routes")]
174impl<T: crate::client_trait::NoauthClient + Sync> NoauthClient for T {}
175#[cfg(feature = "sync_routes")]
176impl<T: crate::client_trait::UserAuthClient + Sync> UserAuthClient for T {}
177#[cfg(feature = "sync_routes")]
178impl<T: crate::client_trait::TeamAuthClient + Sync> TeamAuthClient for T {}
179#[cfg(feature = "sync_routes")]
180impl<T: crate::client_trait::AppAuthClient + Sync> AppAuthClient for T {}
181
182#[cfg(feature = "sync_routes")]
183pub(crate) struct SyncReadAdapter {
184    pub inner: Box<dyn std::io::Read + Send>,
185}
186
187#[cfg(feature = "sync_routes")]
188impl AsyncRead for SyncReadAdapter {
189    fn poll_read(
190        mut self: std::pin::Pin<&mut Self>,
191        _cx: &mut std::task::Context<'_>,
192        buf: &mut [u8],
193    ) -> std::task::Poll<std::io::Result<usize>> {
194        std::task::Poll::Ready(std::io::Read::read(&mut self.inner, buf))
195    }
196
197    fn poll_read_vectored(
198        mut self: std::pin::Pin<&mut Self>,
199        _cx: &mut std::task::Context<'_>,
200        bufs: &mut [std::io::IoSliceMut<'_>],
201    ) -> std::task::Poll<std::io::Result<usize>> {
202        std::task::Poll::Ready(std::io::Read::read_vectored(&mut self.inner, bufs))
203    }
204}