diff options
author | Katharina Fey <kookie@spacekookie.de> | 2021-01-02 22:24:05 +0100 |
---|---|---|
committer | Katharina Fey <kookie@spacekookie.de> | 2021-01-08 02:29:09 +0100 |
commit | 17bb1561b384a92e4c3c50007ac38b2d9b86c95b (patch) | |
tree | 476dc91c61502ad6fa82c83bb05c5812e89aadfa /apps | |
parent | 7a7c3f0adf32382b478b18f745ffd62dcaaa4940 (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
Diffstat (limited to 'apps')
-rw-r--r-- | apps/servers/octopus/supergit/src/lib.rs | 1 | ||||
-rw-r--r-- | apps/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 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![] } |