opendal/services/github/
lister.rs1use std::sync::Arc;
19
20use super::core::GithubCore;
21use crate::raw::oio::Entry;
22use crate::raw::*;
23use crate::*;
24
25pub struct GithubLister {
26 core: Arc<GithubCore>,
27
28 path: String,
29 recursive: bool,
30}
31
32impl GithubLister {
33 pub fn new(core: Arc<GithubCore>, path: &str, recursive: bool) -> Self {
34 Self {
35 core,
36
37 path: path.to_string(),
38 recursive,
39 }
40 }
41}
42
43impl oio::PageList for GithubLister {
44 async fn next_page(&self, ctx: &mut oio::PageContext) -> Result<()> {
45 let resp = self.core.list(&self.path).await?;
46
47 let has_dir = resp.entries.iter().any(|e| e.type_field == "dir");
49
50 ctx.done = true;
51
52 if !self.recursive || !has_dir {
53 for entry in resp.entries {
54 let path = build_rel_path(&self.core.root, &entry.path);
55 let entry = if entry.type_field == "dir" {
56 let path = format!("{}/", path);
57 Entry::new(&path, Metadata::new(EntryMode::DIR))
58 } else {
59 if path.ends_with(".gitkeep") {
60 continue;
61 }
62 let m = Metadata::new(EntryMode::FILE)
63 .with_content_length(entry.size)
64 .with_etag(entry.sha);
65 Entry::new(&path, m)
66 };
67 ctx.entries.push_back(entry);
68 }
69 if !self.path.ends_with('/') {
70 ctx.entries.push_back(Entry::new(
71 &format!("{}/", self.path),
72 Metadata::new(EntryMode::DIR),
73 ));
74 }
75 return Ok(());
76 }
77
78 let tree = self.core.list_with_recursive(&resp.git_url).await?;
81 for t in tree {
82 let path = if self.path == "/" {
83 t.path
84 } else {
85 format!("{}/{}", self.path, t.path)
86 };
87 let entry = if t.type_field == "tree" {
88 let path = format!("{}/", path);
89 Entry::new(&path, Metadata::new(EntryMode::DIR))
90 } else {
91 if path.ends_with(".gitkeep") {
92 continue;
93 }
94 let mut m = Metadata::new(EntryMode::FILE).with_etag(t.sha);
95
96 if let Some(size) = t.size {
97 m = m.with_content_length(size);
98 }
99 Entry::new(&path, m)
100 };
101 ctx.entries.push_back(entry);
102 }
103 if !self.path.ends_with('/') {
104 ctx.entries.push_back(Entry::new(
105 &format!("{}/", self.path),
106 Metadata::new(EntryMode::DIR),
107 ));
108 }
109
110 Ok(())
111 }
112}