opendal/services/dropbox/
builder.rs1use std::fmt::Debug;
19use std::fmt::Formatter;
20use std::sync::Arc;
21
22use chrono::DateTime;
23use chrono::Utc;
24use tokio::sync::Mutex;
25
26use super::backend::DropboxBackend;
27use super::core::DropboxCore;
28use super::core::DropboxSigner;
29use crate::raw::*;
30use crate::services::DropboxConfig;
31use crate::*;
32
33impl Configurator for DropboxConfig {
34 type Builder = DropboxBuilder;
35
36 #[allow(deprecated)]
37 fn into_builder(self) -> Self::Builder {
38 DropboxBuilder {
39 config: self,
40 http_client: None,
41 }
42 }
43}
44
45#[doc = include_str!("docs.md")]
47#[derive(Default)]
48pub struct DropboxBuilder {
49 config: DropboxConfig,
50
51 #[deprecated(since = "0.53.0", note = "Use `Operator::update_http_client` instead")]
52 http_client: Option<HttpClient>,
53}
54
55impl Debug for DropboxBuilder {
56 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
57 f.debug_struct("Builder")
58 .field("root", &self.config.root)
59 .finish()
60 }
61}
62
63impl DropboxBuilder {
64 pub fn root(mut self, root: &str) -> Self {
68 self.config.root = if root.is_empty() {
69 None
70 } else {
71 Some(root.to_string())
72 };
73
74 self
75 }
76
77 pub fn access_token(mut self, access_token: &str) -> Self {
84 self.config.access_token = Some(access_token.to_string());
85 self
86 }
87
88 pub fn refresh_token(mut self, refresh_token: &str) -> Self {
94 self.config.refresh_token = Some(refresh_token.to_string());
95 self
96 }
97
98 pub fn client_id(mut self, client_id: &str) -> Self {
102 self.config.client_id = Some(client_id.to_string());
103 self
104 }
105
106 pub fn client_secret(mut self, client_secret: &str) -> Self {
110 self.config.client_secret = Some(client_secret.to_string());
111 self
112 }
113
114 #[deprecated(since = "0.53.0", note = "Use `Operator::update_http_client` instead")]
121 #[allow(deprecated)]
122 pub fn http_client(mut self, http_client: HttpClient) -> Self {
123 self.http_client = Some(http_client);
124 self
125 }
126}
127
128impl Builder for DropboxBuilder {
129 const SCHEME: Scheme = Scheme::Dropbox;
130 type Config = DropboxConfig;
131
132 fn build(self) -> Result<impl Access> {
133 let root = normalize_root(&self.config.root.unwrap_or_default());
134
135 let signer = match (self.config.access_token, self.config.refresh_token) {
136 (Some(access_token), None) => DropboxSigner {
137 access_token,
138 expires_in: DateTime::<Utc>::MAX_UTC,
140 ..Default::default()
141 },
142 (None, Some(refresh_token)) => {
143 let client_id = self.config.client_id.ok_or_else(|| {
144 Error::new(
145 ErrorKind::ConfigInvalid,
146 "client_id must be set when refresh_token is set",
147 )
148 .with_context("service", Scheme::Dropbox)
149 })?;
150 let client_secret = self.config.client_secret.ok_or_else(|| {
151 Error::new(
152 ErrorKind::ConfigInvalid,
153 "client_secret must be set when refresh_token is set",
154 )
155 .with_context("service", Scheme::Dropbox)
156 })?;
157
158 DropboxSigner {
159 refresh_token,
160 client_id,
161 client_secret,
162 ..Default::default()
163 }
164 }
165 (Some(_), Some(_)) => {
166 return Err(Error::new(
167 ErrorKind::ConfigInvalid,
168 "access_token and refresh_token can not be set at the same time",
169 )
170 .with_context("service", Scheme::Dropbox))
171 }
172 (None, None) => {
173 return Err(Error::new(
174 ErrorKind::ConfigInvalid,
175 "access_token or refresh_token must be set",
176 )
177 .with_context("service", Scheme::Dropbox))
178 }
179 };
180
181 Ok(DropboxBackend {
182 core: Arc::new(DropboxCore {
183 info: {
184 let am = AccessorInfo::default();
185 am.set_scheme(Scheme::Dropbox)
186 .set_root(&root)
187 .set_native_capability(Capability {
188 stat: true,
189 stat_has_last_modified: true,
190 stat_has_content_length: true,
191
192 read: true,
193
194 write: true,
195
196 create_dir: true,
197
198 delete: true,
199
200 list: true,
201 list_with_recursive: true,
202 list_has_last_modified: true,
203 list_has_content_length: true,
204
205 copy: true,
206
207 rename: true,
208
209 shared: true,
210
211 ..Default::default()
212 });
213
214 #[allow(deprecated)]
216 if let Some(client) = self.http_client {
217 am.update_http_client(|_| client);
218 }
219
220 am.into()
221 },
222 root,
223 signer: Arc::new(Mutex::new(signer)),
224 }),
225 })
226 }
227}