@ -33,6 +33,7 @@ pub struct FileInfo
state : Arc < Config > , //TODO: XXX: This will be a *severe* slowdown... How can we have just a reference here? Thread local? `tokio::task_local!`? Global static?
path : PathBuf ,
meta : Metadata ,
dir : bool ,
}
impl FileInfo
@ -53,6 +54,7 @@ impl FileInfo
{
Self {
state : config . into ( ) ,
dir : meta . is_dir ( ) ,
path , meta
}
}
@ -122,6 +124,46 @@ impl order::Orderer<FileInfo> for FileInfo
#[ derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default) ]
pub struct FSTimeMap ( Arc < Config > , BTreeSet < order ::Ordered < FileInfo , FileInfo > > ) ;
/// Maps files based on their time maintaining directory structure.
///
/// # Note
/// The output of this ordering is still a flat-map. Children are corrently grouped beneath their parents.
#[ derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default) ]
pub struct NestedFsTreeMap ( Arc < Config > , BTreeSet < order ::Ordered < NestedFileInfo , FileInfo > > ) ;
impl NestedFsTreeMap
{
#[ inline ]
pub fn new ( config : impl Into < Config > ) -> Self
{
Self ( Arc ::new ( config . into ( ) ) , BTreeSet ::new ( ) )
}
#[ inline ]
pub fn iter ( & self ) -> impl Iterator < Item = & ' _ FileInfo > + ExactSizeIterator + DoubleEndedIterator + std ::iter ::FusedIterator + ' _
{
self . 1. iter ( ) . map ( | x | & x . inner ( ) . file )
}
#[ inline ]
pub fn into_iter ( self ) -> impl Iterator < Item = FileInfo > + ExactSizeIterator + DoubleEndedIterator + std ::iter ::FusedIterator + ' static
{
self . 1. into_iter ( ) . map ( | x | x . into_inner ( ) . file )
}
#[ inline ]
pub fn insert ( & mut self , parent : impl Into < Option < FileInfo > > , file : FileInfo )
{
self . 1. insert ( order ::Ordered ::new ( NestedFileInfo ::new ( parent . into ( ) , file ) ) ) ;
}
#[ inline ]
pub fn len ( & self ) -> usize
{
self . 1. len ( )
}
}
impl FSTimeMap
{
#[ inline ]
@ -154,3 +196,72 @@ impl FSTimeMap
self . 1. len ( )
}
}
/// Tree-maintaining file info
#[ derive(Debug, Clone) ]
pub struct NestedFileInfo
{
file : FileInfo ,
parent : Option < FileInfo >
}
impl NestedFileInfo
{
#[ inline ]
pub fn new ( parent : Option < FileInfo > , file : FileInfo ) -> Self
{
Self {
file ,
parent ,
}
}
#[ inline ]
pub fn into_inner ( self ) -> FileInfo
{
self . file
}
#[ inline ]
pub fn parent ( & self ) -> Option < & FileInfo >
{
self . parent . as_ref ( )
}
}
impl order ::Orderer < NestedFileInfo > for FileInfo
{
#[ inline ]
fn order ( a : & NestedFileInfo , b : & NestedFileInfo ) -> std ::cmp ::Ordering {
if let Some ( parent ) = & a . parent {
// Check if `b` is parent of `a`, if so, `a` *always* comes after `b`
if parent . path ( ) = = b . file . path ( ) {
return std ::cmp ::Ordering ::Greater ;
}
// If `a`'s parent is not the same as `b`'s parent, then `a` always comes *before* `b`.
if let Some ( bparent ) = & b . parent {
if ! FileInfo ::order ( parent , bparent ) . is_eq ( ) {
return std ::cmp ::Ordering ::Less ;
}
}
}
if let Some ( parent ) = & b . parent {
// Check if `a` is parent of `b`, if so, `b` *always* comes after `a`.
if parent . path ( ) = = a . file . path ( ) {
return std ::cmp ::Ordering ::Less ;
}
// If `b`'s parent is not the same as `a`'s parent, then `b` always comes *before* `a`.
if let Some ( aparent ) = & a . parent {
if ! FileInfo ::order ( parent , aparent ) . is_eq ( ) {
return std ::cmp ::Ordering ::Greater ;
}
}
}
FileInfo ::order ( & a . file , & b . file )
}
}