opendal/services/onedrive/
builder.rs1use std::fmt::Debug;
19use std::fmt::Formatter;
20use std::sync::Arc;
21
22use chrono::DateTime;
23use chrono::Utc;
24use log::debug;
25use services::onedrive::core::OneDriveCore;
26use services::onedrive::core::OneDriveSigner;
27
28use tokio::sync::Mutex;
29
30use super::backend::OnedriveBackend;
31use crate::raw::normalize_root;
32use crate::raw::Access;
33use crate::raw::AccessorInfo;
34use crate::raw::HttpClient;
35use crate::services::OnedriveConfig;
36use crate::Scheme;
37use crate::*;
38
39impl Configurator for OnedriveConfig {
40 type Builder = OnedriveBuilder;
41 fn into_builder(self) -> Self::Builder {
42 OnedriveBuilder {
43 config: self,
44 http_client: None,
45 }
46 }
47}
48
49#[doc = include_str!("docs.md")]
51#[derive(Default)]
52pub struct OnedriveBuilder {
53 config: OnedriveConfig,
54 http_client: Option<HttpClient>,
55}
56
57impl Debug for OnedriveBuilder {
58 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
59 f.debug_struct("Backend")
60 .field("config", &self.config)
61 .finish()
62 }
63}
64
65impl OnedriveBuilder {
66 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 #[deprecated(since = "0.53.0", note = "Use `Operator::update_http_client` instead")]
84 #[allow(deprecated)]
85 pub fn http_client(mut self, http_client: HttpClient) -> Self {
86 self.http_client = Some(http_client);
87 self
88 }
89
90 pub fn access_token(mut self, access_token: &str) -> Self {
100 self.config.access_token = Some(access_token.to_string());
101 self
102 }
103
104 pub fn refresh_token(mut self, refresh_token: &str) -> Self {
112 self.config.refresh_token = Some(refresh_token.to_string());
113 self
114 }
115
116 pub fn client_id(mut self, client_id: &str) -> Self {
120 self.config.client_id = Some(client_id.to_string());
121 self
122 }
123
124 pub fn client_secret(mut self, client_secret: &str) -> Self {
129 self.config.client_secret = Some(client_secret.to_string());
130 self
131 }
132
133 pub fn enable_versioning(mut self, enabled: bool) -> Self {
135 self.config.enable_versioning = enabled;
136 self
137 }
138}
139
140impl Builder for OnedriveBuilder {
141 const SCHEME: Scheme = Scheme::Onedrive;
142 type Config = OnedriveConfig;
143
144 fn build(self) -> Result<impl Access> {
145 let root = normalize_root(&self.config.root.unwrap_or_default());
146 debug!("backend use root {}", root);
147
148 let info = AccessorInfo::default();
149 info.set_scheme(Scheme::Onedrive)
150 .set_root(&root)
151 .set_native_capability(Capability {
152 read: true,
153 read_with_if_none_match: true,
154
155 write: true,
156 write_with_if_match: true,
157 copy: true,
163 rename: true,
164
165 stat: true,
166 stat_with_if_none_match: true,
167 stat_has_content_length: true,
168 stat_has_etag: true,
169 stat_has_last_modified: true,
170 stat_with_version: self.config.enable_versioning,
171
172 delete: true,
173 create_dir: true,
174
175 list: true,
176 list_with_limit: true,
177 list_with_versions: self.config.enable_versioning,
178 list_has_content_length: true,
179 list_has_etag: true,
180 list_has_last_modified: true,
181 list_has_version: self.config.enable_versioning, shared: true,
184
185 ..Default::default()
186 });
187
188 #[allow(deprecated)]
190 if let Some(client) = self.http_client {
191 info.update_http_client(|_| client);
192 }
193
194 let accessor_info = Arc::new(info);
195 let mut signer = OneDriveSigner::new(accessor_info.clone());
196
197 match (self.config.access_token, self.config.refresh_token) {
202 (Some(access_token), None) => {
203 signer.access_token = access_token;
204 signer.expires_in = DateTime::<Utc>::MAX_UTC;
205 }
206 (None, Some(refresh_token)) => {
207 let client_id = self.config.client_id.ok_or_else(|| {
208 Error::new(
209 ErrorKind::ConfigInvalid,
210 "client_id must be set when refresh_token is set",
211 )
212 .with_context("service", Scheme::Onedrive)
213 })?;
214
215 signer.refresh_token = refresh_token;
216 signer.client_id = client_id;
217 if let Some(client_secret) = self.config.client_secret {
218 signer.client_secret = client_secret;
219 }
220 }
221 (Some(_), Some(_)) => {
222 return Err(Error::new(
223 ErrorKind::ConfigInvalid,
224 "access_token and refresh_token cannot be set at the same time",
225 )
226 .with_context("service", Scheme::Onedrive))
227 }
228 (None, None) => {
229 return Err(Error::new(
230 ErrorKind::ConfigInvalid,
231 "access_token or refresh_token must be set",
232 )
233 .with_context("service", Scheme::Onedrive))
234 }
235 };
236
237 let core = Arc::new(OneDriveCore {
238 info: accessor_info,
239 root,
240 signer: Arc::new(Mutex::new(signer)),
241 });
242
243 Ok(OnedriveBackend { core })
244 }
245}