opendal/services/gdrive/
builder.rs1use std::fmt::Debug;
19use std::sync::Arc;
20
21use log::debug;
22use tokio::sync::Mutex;
23
24use super::GDRIVE_SCHEME;
25use super::backend::GdriveBackend;
26use super::config::GdriveConfig;
27use super::core::GdriveCore;
28use super::core::GdrivePathQuery;
29use super::core::GdriveSigner;
30use crate::raw::*;
31use crate::*;
32
33#[derive(Default)]
35#[doc = include_str!("docs.md")]
36pub struct GdriveBuilder {
37 pub(super) config: GdriveConfig,
38
39 #[deprecated(since = "0.53.0", note = "Use `Operator::update_http_client` instead")]
40 pub(super) http_client: Option<HttpClient>,
41}
42
43impl Debug for GdriveBuilder {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 f.debug_struct("GdriveBuilder")
46 .field("config", &self.config)
47 .finish_non_exhaustive()
48 }
49}
50
51impl GdriveBuilder {
52 pub fn root(mut self, root: &str) -> Self {
54 self.config.root = if root.is_empty() {
55 None
56 } else {
57 Some(root.to_string())
58 };
59
60 self
61 }
62
63 pub fn access_token(mut self, access_token: &str) -> Self {
74 self.config.access_token = Some(access_token.to_string());
75 self
76 }
77
78 pub fn refresh_token(mut self, refresh_token: &str) -> Self {
84 self.config.refresh_token = Some(refresh_token.to_string());
85 self
86 }
87
88 pub fn client_id(mut self, client_id: &str) -> Self {
92 self.config.client_id = Some(client_id.to_string());
93 self
94 }
95
96 pub fn client_secret(mut self, client_secret: &str) -> Self {
100 self.config.client_secret = Some(client_secret.to_string());
101 self
102 }
103
104 #[deprecated(since = "0.53.0", note = "Use `Operator::update_http_client` instead")]
111 #[allow(deprecated)]
112 pub fn http_client(mut self, http_client: HttpClient) -> Self {
113 self.http_client = Some(http_client);
114 self
115 }
116}
117
118impl Builder for GdriveBuilder {
119 type Config = GdriveConfig;
120
121 fn build(self) -> Result<impl Access> {
122 let root = normalize_root(&self.config.root.unwrap_or_default());
123 debug!("backend use root {root}");
124
125 let info = AccessorInfo::default();
126 info.set_scheme(GDRIVE_SCHEME)
127 .set_root(&root)
128 .set_native_capability(Capability {
129 stat: true,
130
131 read: true,
132
133 list: true,
134
135 write: true,
136
137 create_dir: true,
138 delete: true,
139 rename: true,
140 copy: true,
141
142 shared: true,
143
144 ..Default::default()
145 });
146
147 #[allow(deprecated)]
149 if let Some(client) = self.http_client {
150 info.update_http_client(|_| client);
151 }
152
153 let accessor_info = Arc::new(info);
154 let mut signer = GdriveSigner::new(accessor_info.clone());
155 match (self.config.access_token, self.config.refresh_token) {
156 (Some(access_token), None) => {
157 signer.access_token = access_token;
158 signer.expires_in = Timestamp::MAX;
160 }
161 (None, Some(refresh_token)) => {
162 let client_id = self.config.client_id.ok_or_else(|| {
163 Error::new(
164 ErrorKind::ConfigInvalid,
165 "client_id must be set when refresh_token is set",
166 )
167 .with_context("service", GDRIVE_SCHEME)
168 })?;
169 let client_secret = self.config.client_secret.ok_or_else(|| {
170 Error::new(
171 ErrorKind::ConfigInvalid,
172 "client_secret must be set when refresh_token is set",
173 )
174 .with_context("service", GDRIVE_SCHEME)
175 })?;
176
177 signer.refresh_token = refresh_token;
178 signer.client_id = client_id;
179 signer.client_secret = client_secret;
180 }
181 (Some(_), Some(_)) => {
182 return Err(Error::new(
183 ErrorKind::ConfigInvalid,
184 "access_token and refresh_token cannot be set at the same time",
185 )
186 .with_context("service", GDRIVE_SCHEME));
187 }
188 (None, None) => {
189 return Err(Error::new(
190 ErrorKind::ConfigInvalid,
191 "access_token or refresh_token must be set",
192 )
193 .with_context("service", GDRIVE_SCHEME));
194 }
195 };
196
197 let signer = Arc::new(Mutex::new(signer));
198
199 Ok(GdriveBackend {
200 core: Arc::new(GdriveCore {
201 info: accessor_info.clone(),
202 root,
203 signer: signer.clone(),
204 path_cache: PathCacher::new(GdrivePathQuery::new(accessor_info, signer))
205 .with_lock(),
206 }),
207 })
208 }
209}