opendal/services/gdrive/
backend.rs1use std::fmt::Debug;
19use std::sync::Arc;
20
21use super::core::GdriveCore;
22use super::core::GdriveFile;
23use super::delete::GdriveDeleter;
24use super::error::parse_error;
25use super::lister::GdriveLister;
26use super::writer::GdriveWriter;
27use crate::raw::*;
28use crate::*;
29use bytes::Buf;
30use http::Response;
31use http::StatusCode;
32
33#[derive(Clone, Debug)]
34pub struct GdriveBackend {
35 pub core: Arc<GdriveCore>,
36}
37
38impl Access for GdriveBackend {
39 type Reader = HttpBody;
40 type Writer = oio::OneShotWriter<GdriveWriter>;
41 type Lister = oio::PageLister<GdriveLister>;
42 type Deleter = oio::OneShotDeleter<GdriveDeleter>;
43
44 fn info(&self) -> Arc<AccessorInfo> {
45 self.core.info.clone()
46 }
47
48 async fn create_dir(&self, path: &str, _args: OpCreateDir) -> Result<RpCreateDir> {
49 let path = build_abs_path(&self.core.root, path);
50 let _ = self.core.path_cache.ensure_dir(&path).await?;
51
52 Ok(RpCreateDir::default())
53 }
54
55 async fn stat(&self, path: &str, _args: OpStat) -> Result<RpStat> {
56 let resp = self.core.gdrive_stat(path).await?;
57
58 if resp.status() != StatusCode::OK {
59 return Err(parse_error(resp));
60 }
61
62 let bs = resp.into_body();
63 let gdrive_file: GdriveFile =
64 serde_json::from_reader(bs.reader()).map_err(new_json_deserialize_error)?;
65
66 let file_type = if gdrive_file.mime_type == "application/vnd.google-apps.folder" {
67 EntryMode::DIR
68 } else {
69 EntryMode::FILE
70 };
71 let mut meta = Metadata::new(file_type).with_content_type(gdrive_file.mime_type);
72 if let Some(v) = gdrive_file.size {
73 meta = meta.with_content_length(v.parse::<u64>().map_err(|e| {
74 Error::new(ErrorKind::Unexpected, "parse content length").set_source(e)
75 })?);
76 }
77 if let Some(v) = gdrive_file.modified_time {
78 meta = meta.with_last_modified(v.parse::<Timestamp>().map_err(|e| {
79 Error::new(ErrorKind::Unexpected, "parse last modified time").set_source(e)
80 })?);
81 }
82 Ok(RpStat::new(meta))
83 }
84
85 async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> {
86 let resp = self.core.gdrive_get(path, args.range()).await?;
87
88 let status = resp.status();
89 match status {
90 StatusCode::OK | StatusCode::PARTIAL_CONTENT => Ok((RpRead::new(), resp.into_body())),
91 _ => {
92 let (part, mut body) = resp.into_parts();
93 let buf = body.to_buffer().await?;
94 Err(parse_error(Response::from_parts(part, buf)))
95 }
96 }
97 }
98
99 async fn write(&self, path: &str, _: OpWrite) -> Result<(RpWrite, Self::Writer)> {
100 let path = build_abs_path(&self.core.root, path);
101
102 let file_id = self.core.path_cache.get(&path).await?;
105
106 Ok((
107 RpWrite::default(),
108 oio::OneShotWriter::new(GdriveWriter::new(self.core.clone(), path, file_id)),
109 ))
110 }
111
112 async fn delete(&self) -> Result<(RpDelete, Self::Deleter)> {
113 Ok((
114 RpDelete::default(),
115 oio::OneShotDeleter::new(GdriveDeleter::new(self.core.clone())),
116 ))
117 }
118
119 async fn list(&self, path: &str, _args: OpList) -> Result<(RpList, Self::Lister)> {
120 let path = build_abs_path(&self.core.root, path);
121 let l = GdriveLister::new(path, self.core.clone());
122 Ok((RpList::default(), oio::PageLister::new(l)))
123 }
124
125 async fn copy(&self, from: &str, to: &str, _args: OpCopy) -> Result<RpCopy> {
126 let resp = self.core.gdrive_copy(from, to).await?;
127
128 match resp.status() {
129 StatusCode::OK => Ok(RpCopy::default()),
130 _ => Err(parse_error(resp)),
131 }
132 }
133
134 async fn rename(&self, from: &str, to: &str, _args: OpRename) -> Result<RpRename> {
135 let source = build_abs_path(&self.core.root, from);
136 let target = build_abs_path(&self.core.root, to);
137
138 if let Some(id) = self.core.path_cache.get(&target).await? {
140 let resp = self.core.gdrive_trash(&id).await?;
141 let status = resp.status();
142 if status != StatusCode::OK {
143 return Err(parse_error(resp));
144 }
145
146 self.core.path_cache.remove(&target).await;
147 }
148
149 let resp = self
150 .core
151 .gdrive_patch_metadata_request(&source, &target)
152 .await?;
153
154 let status = resp.status();
155
156 match status {
157 StatusCode::OK => {
158 let body = resp.into_body();
159 let meta: GdriveFile =
160 serde_json::from_reader(body.reader()).map_err(new_json_deserialize_error)?;
161
162 let cache = &self.core.path_cache;
163
164 cache.remove(&build_abs_path(&self.core.root, from)).await;
165 cache
166 .insert(&build_abs_path(&self.core.root, to), &meta.id)
167 .await;
168
169 Ok(RpRename::default())
170 }
171 _ => Err(parse_error(resp)),
172 }
173 }
174}