@ -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! [ ]
}