use std::sync::Arc;
use super::core::GithubCore;
use opendal_core::raw::oio::Entry;
use opendal_core::raw::*;
use opendal_core::*;
pub struct GithubLister {
core: Arc<GithubCore>,
ctx: OperationContext,
path: String,
recursive: bool,
}
impl GithubLister {
pub fn new(core: Arc<GithubCore>, ctx: OperationContext, path: &str, recursive: bool) -> Self {
Self {
core,
ctx,
path: path.to_string(),
recursive,
}
}
}
impl oio::PageList for GithubLister {
async fn next_page(&self, ctx: &mut oio::PageContext) -> Result<()> {
let resp = self.core.list(&self.ctx, &self.path).await?;
let has_dir = resp.entries.iter().any(|e| e.type_field == "dir");
ctx.done = true;
if !self.recursive || !has_dir {
for entry in resp.entries {
let path = build_rel_path(&self.core.root, &entry.path);
let entry = if entry.type_field == "dir" {
let path = format!("{path}/");
Entry::new(&path, Metadata::new(EntryMode::DIR))
} else {
if path.ends_with(".gitkeep") {
continue;
}
let m = Metadata::new(EntryMode::FILE)
.with_content_length(entry.size)
.with_etag(entry.sha);
Entry::new(&path, m)
};
ctx.entries.push_back(entry);
}
if !self.path.ends_with('/') {
ctx.entries.push_back(Entry::new(
&format!("{}/", self.path),
Metadata::new(EntryMode::DIR),
));
}
return Ok(());
}
let tree = self
.core
.list_with_recursive(&self.ctx, &resp.git_url)
.await?;
for t in tree {
let path = if self.path == "/" {
t.path
} else {
format!("{}/{}", self.path, t.path)
};
let entry = if t.type_field == "tree" {
let path = format!("{path}/");
Entry::new(&path, Metadata::new(EntryMode::DIR))
} else {
if path.ends_with(".gitkeep") {
continue;
}
let mut m = Metadata::new(EntryMode::FILE).with_etag(t.sha);
if let Some(size) = t.size {
m = m.with_content_length(size);
}
Entry::new(&path, m)
};
ctx.entries.push_back(entry);
}
if !self.path.ends_with('/') {
ctx.entries.push_back(Entry::new(
&format!("{}/", self.path),
Metadata::new(EntryMode::DIR),
));
}
Ok(())
}
}