dropbox_sdk/
async_client_trait.rs1pub use crate::client_trait_common::{HttpRequest, TeamSelect};
4use crate::Error;
5use bytes::Bytes;
6use futures::AsyncRead;
7use std::future::{ready, Future};
8use std::sync::Arc;
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 {
73 unimplemented!()
74 }
75 }
76}
77
78pub struct HttpRequestResultRaw {
80 pub status: u16,
82
83 pub result_header: Option<String>,
85
86 pub content_length: Option<u64>,
88
89 pub body: Box<dyn AsyncRead + Send + Unpin>,
91}
92
93pub struct HttpRequestResult<T> {
96 pub result: T,
98
99 pub content_length: Option<u64>,
102
103 pub body: Option<Box<dyn AsyncRead + Unpin + Send>>,
106}
107
108#[cfg(feature = "sync_routes")]
112impl<T: crate::client_trait::HttpClient + Sync> HttpClient for T {
113 type Request = T::Request;
114
115 async fn execute(
116 &self,
117 request: Self::Request,
118 body: Bytes,
119 ) -> Result<HttpRequestResultRaw, Error> {
120 self.execute_borrowed_body(request, &body).await
121 }
122
123 async fn execute_borrowed_body(
124 &self,
125 request: Self::Request,
126 body_slice: &[u8],
127 ) -> Result<HttpRequestResultRaw, Error> {
128 self.execute(request, body_slice)
129 .map(|r| HttpRequestResultRaw {
130 status: r.status,
131 result_header: r.result_header,
132 content_length: r.content_length,
133 body: Box::new(SyncReadAdapter { inner: r.body }),
134 })
135 }
136
137 fn new_request(&self, url: &str) -> Self::Request {
138 self.new_request(url)
139 }
140
141 fn update_token(
142 &self,
143 old_token: Arc<String>,
144 ) -> impl Future<Output = Result<bool, Error>> + Send {
145 ready(self.update_token(old_token))
146 }
147
148 fn token(&self) -> Option<Arc<String>> {
149 self.token()
150 }
151
152 fn path_root(&self) -> Option<&str> {
153 self.path_root()
154 }
155
156 fn team_select(&self) -> Option<&TeamSelect> {
157 self.team_select()
158 }
159}
160
161pub trait NoauthClient: HttpClient {}
163
164pub trait UserAuthClient: HttpClient {}
167
168pub trait TeamAuthClient: HttpClient {}
172
173pub trait AppAuthClient: HttpClient {}
177
178#[cfg(feature = "sync_routes")]
180impl<T: crate::client_trait::NoauthClient + Sync> NoauthClient for T {}
181#[cfg(feature = "sync_routes")]
182impl<T: crate::client_trait::UserAuthClient + Sync> UserAuthClient for T {}
183#[cfg(feature = "sync_routes")]
184impl<T: crate::client_trait::TeamAuthClient + Sync> TeamAuthClient for T {}
185#[cfg(feature = "sync_routes")]
186impl<T: crate::client_trait::AppAuthClient + Sync> AppAuthClient for T {}
187
188#[cfg(feature = "sync_routes")]
189pub(crate) struct SyncReadAdapter {
190 pub inner: Box<dyn std::io::Read + Send>,
191}
192
193#[cfg(feature = "sync_routes")]
194impl AsyncRead for SyncReadAdapter {
195 fn poll_read(
196 mut self: std::pin::Pin<&mut Self>,
197 _cx: &mut std::task::Context<'_>,
198 buf: &mut [u8],
199 ) -> std::task::Poll<std::io::Result<usize>> {
200 std::task::Poll::Ready(std::io::Read::read(&mut self.inner, buf))
201 }
202
203 fn poll_read_vectored(
204 mut self: std::pin::Pin<&mut Self>,
205 _cx: &mut std::task::Context<'_>,
206 bufs: &mut [std::io::IoSliceMut<'_>],
207 ) -> std::task::Poll<std::io::Result<usize>> {
208 std::task::Poll::Ready(std::io::Read::read_vectored(&mut self.inner, bufs))
209 }
210}