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