aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2021-01-02 22:24:05 +0100
committerKatharina Fey <kookie@spacekookie.de>2021-01-08 02:29:09 +0100
commit17bb1561b384a92e4c3c50007ac38b2d9b86c95b (patch)
tree476dc91c61502ad6fa82c83bb05c5812e89aadfa
parent7a7c3f0adf32382b478b18f745ffd62dcaaa4940 (diff)
supergit: implement typed directory yields
Previously a Yield object was either a file dump, or a simple enumeration on a directories children, with no associated type state for them. This commit implements a mechanism to internally fetch this type information, to pass out to a user via the Yield type. This way it is much easier to figure out which entries are directories, and which are files. Additional queries have to be passed into the FileTree for lookups. In a way, this commit gives up on the idea of having a nested API structure for the time being, until constructing sub-FileTrees becomes a real necessity
-rw-r--r--apps/servers/octopus/supergit/src/lib.rs1
-rw-r--r--apps/servers/octopus/supergit/src/old-files.rs59
2 files changed, 43 insertions, 17 deletions
diff --git a/apps/servers/octopus/supergit/src/lib.rs b/apps/servers/octopus/supergit/src/lib.rs
index e7414c2862a7..ee02daac39c8 100644
--- a/apps/servers/octopus/supergit/src/lib.rs
+++ b/apps/servers/octopus/supergit/src/lib.rs
@@ -35,3 +35,4 @@ pub mod prelude {
pub use crate::files::{EntryType, Explorer, TreeEntry};
pub use crate::{Commit, Diff, Repository};
}
+
diff --git a/apps/servers/octopus/supergit/src/old-files.rs b/apps/servers/octopus/supergit/src/old-files.rs
index a4b10513c7fb..750e630ca99b 100644
--- a/apps/servers/octopus/supergit/src/old-files.rs
+++ b/apps/servers/octopus/supergit/src/old-files.rs
@@ -73,8 +73,8 @@ impl FileTree {
/// (returns `None`), because directories can't be loaded. If you
/// want to get a list of children for a directory, use
/// [`FileTree::enumerate()`]() instead!
- pub fn load(&self, path: &str) -> Option<Yield> {
- self.get_entry(path).and_then(|e| e.load(&self.repo))
+ pub fn load(self: &Arc<Self>, path: &str) -> Option<Yield> {
+ self.get_entry(path).and_then(|e| e.load(self))
}
/// Get the history of a path with a branch iterator
@@ -103,18 +103,31 @@ impl FileTree {
///
/// This type is returned when fetching a path via `FileTree::load()`,
/// and can either be a single file read into memory, or an
-/// enumeration of direct children of a directory.
+/// enumeration of direct children of a directory. In this case, the
+/// information about child status (file or directory) is fetched
+/// during creation from the underlying repository.
///
-/// To get all children of a subtree, use `Yield::into_tree()` to
-/// create a new, recursive `FileTree` to enumerate.
+/// In order to traverse the next level of the subtree, you need to
+/// append a child name to the existing path, and run
+/// [`FileTree::load()`](FileTree::load) again.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Yield {
/// Load a single file into a buffer
File(Vec<u8>),
/// Enumerate children in a directory
- Dir(Vec<String>),
+ Dir(Vec<YieldEntry>),
}
+/// Simple type to disambiguate between files and directories
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub enum YieldEntry {
+ /// A file name
+ File(String),
+ /// A directory name
+ Dir(String),
+}
+
+#[derive(Debug)]
enum TreeEntry {
/// A single file
File(File),
@@ -135,15 +148,16 @@ impl TreeEntry {
}
}
- fn load(&self, repo: &Arc<git2::Repository>) -> Option<Yield> {
+ fn load(&self, ft: &Arc<FileTree>) -> Option<Yield> {
let id = self.id();
+ let repo = &ft.repo;
match self {
- Self::File(ref f) => repo
+ Self::File(_) => repo
.find_blob(id.into())
.ok()
.map(|b| Yield::File(b.content().into())),
- Self::Dir(ref d) => repo
+ Self::Dir(_) => repo
.find_tree(id.into())
.ok()
.map(|tree| {
@@ -156,14 +170,22 @@ impl TreeEntry {
if path_segs.len() > 0 {
TreeWalkResult::Skip
} else {
- // Take the current tree path, and append the
- // name of whatever we're currently iterating
- // over is
+ // Take the current tree path and append
+ // the name of the current entry on it
let path = PathBuf::new().join(self.path()).join(entry.name().unwrap());
- children.push(path.as_path().to_str().unwrap().into());
+ let s: String = path.as_path().to_str().unwrap().into();
+
+ // Construct a YieldEntry via a FileTree lookup
+ children.push(if ft.get_entry(s.as_str()).unwrap().is_directory() {
+ YieldEntry::Dir(s)
+ } else {
+ YieldEntry::File(s)
+ });
+
TreeWalkResult::Ok
}
- });
+ })
+ .unwrap();
children
})
@@ -171,10 +193,10 @@ impl TreeEntry {
}
}
- fn is_file(&self) -> bool {
+ fn is_directory(&self) -> bool {
match self {
- Self::File(_) => true,
- Self::Dir(_) => false,
+ Self::Dir(_) => true,
+ Self::File(_) => false,
}
}
@@ -201,6 +223,7 @@ impl TreeEntry {
}
}
+#[derive(Debug)]
struct File {
id: HashId,
path: String,
@@ -213,6 +236,7 @@ impl File {
}
}
+#[derive(Debug)]
struct Directory {
id: HashId,
path: String,
@@ -224,6 +248,7 @@ impl Directory {
Self { id, path, name }
}
+ #[allow(unused)]
fn enumerate(&self, repo: git2::Repository) -> Vec<String> {
vec![]
}