From 17bb1561b384a92e4c3c50007ac38b2d9b86c95b Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Sat, 2 Jan 2021 22:24:05 +0100 Subject: [PATCH] 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 --- apps/servers/octopus/supergit/src/lib.rs | 1 + .../servers/octopus/supergit/src/old-files.rs | 59 +++++++++++++------ 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 e7414c2862a..ee02daac39c 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 a4b10513c7f..750e630ca99 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 { - self.get_entry(path).and_then(|e| e.load(&self.repo)) + pub fn load(self: &Arc, path: &str) -> Option { + 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), /// Enumerate children in a directory - Dir(Vec), + Dir(Vec), } +/// 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) -> Option { + fn load(&self, ft: &Arc) -> Option { 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 { vec![] }