opendal/services/gdrive/
lister.rs1use std::sync::Arc;
19
20use http::StatusCode;
21
22use super::core::GdriveCore;
23use super::core::GdriveFileList;
24use super::error::parse_error;
25use crate::raw::*;
26use crate::*;
27
28pub struct GdriveLister {
29 path: String,
30 core: Arc<GdriveCore>,
31}
32
33impl GdriveLister {
34 pub fn new(path: String, core: Arc<GdriveCore>) -> Self {
35 Self { path, core }
36 }
37}
38
39impl oio::PageList for GdriveLister {
40 async fn next_page(&self, ctx: &mut oio::PageContext) -> Result<()> {
41 let file_id = self.core.path_cache.get(&self.path).await?;
42
43 let file_id = match file_id {
44 Some(file_id) => file_id,
45 None => {
46 ctx.done = true;
47 return Ok(());
48 }
49 };
50
51 let resp = self
52 .core
53 .gdrive_list(file_id.as_str(), 100, &ctx.token)
54 .await?;
55
56 let bytes = match resp.status() {
57 StatusCode::OK => resp.into_body().to_bytes(),
58 _ => return Err(parse_error(resp)),
59 };
60
61 if bytes.is_empty() {
63 ctx.done = true;
64 return Ok(());
65 }
66
67 if ctx.token.is_empty() && !ctx.done {
69 let path = build_rel_path(&self.core.root, &self.path);
70 let e = oio::Entry::new(&path, Metadata::new(EntryMode::DIR));
71 ctx.entries.push_back(e);
72 }
73
74 let decoded_response =
75 serde_json::from_slice::<GdriveFileList>(&bytes).map_err(new_json_deserialize_error)?;
76
77 if let Some(next_page_token) = decoded_response.next_page_token {
78 ctx.token = next_page_token;
79 } else {
80 ctx.done = true;
81 }
82
83 for mut file in decoded_response.files {
84 let file_type = if file.mime_type.as_str() == "application/vnd.google-apps.folder" {
85 if !file.name.ends_with('/') {
86 file.name += "/";
87 }
88 EntryMode::DIR
89 } else {
90 EntryMode::FILE
91 };
92
93 let root = &self.core.root;
94 let path = format!("{}{}", &self.path, file.name);
95 let normalized_path = build_rel_path(root, &path);
96
97 if let Ok(None) = self.core.path_cache.get(&path).await {
101 self.core.path_cache.insert(&path, &file.id).await;
102 }
103
104 let entry = oio::Entry::new(&normalized_path, Metadata::new(file_type));
105 ctx.entries.push_back(entry);
106 }
107
108 Ok(())
109 }
110}