diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-07-22 22:29:14 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-07-22 22:32:14 -0400 |
commit | 97ca1fb6d44de66d872422783c38ae198b0edfb9 (patch) | |
tree | 695eacc8aaeda28f32fd839169fb8862caf09571 /src/fs | |
parent | 4385f6eb523ece963b154f2525f82e8e9f3882f1 (diff) |
add automatically_count_files option
- for now, this disables counting number of files in a directory
- future plans is to change this to opportunistic file counting
- i.e. if we already have the directory loaded, then finding the file count
is pretty trivial
- it just requires a bit of refactoring
Diffstat (limited to 'src/fs')
-rw-r--r-- | src/fs/dirlist.rs | 11 | ||||
-rw-r--r-- | src/fs/entry.rs | 71 | ||||
-rw-r--r-- | src/fs/metadata.rs | 20 |
3 files changed, 63 insertions, 39 deletions
diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs index 1414531..80f9089 100644 --- a/src/fs/dirlist.rs +++ b/src/fs/dirlist.rs @@ -1,7 +1,7 @@ use std::slice::{Iter, IterMut}; use std::{fs, path}; -use crate::fs::{JoshutoDirEntry, JoshutoMetadata}; +use crate::fs::{FileType, JoshutoDirEntry, JoshutoMetadata}; use crate::util::display::DisplayOption; #[derive(Clone, Debug)] @@ -16,7 +16,7 @@ pub struct JoshutoDirList { impl JoshutoDirList { pub fn new(path: path::PathBuf, options: &DisplayOption) -> std::io::Result<Self> { let filter_func = options.filter_func(); - let mut contents = read_dir_list(path.as_path(), filter_func, options.show_icons())?; + let mut contents = read_dir_list(path.as_path(), filter_func, &options)?; let sort_options = options.sort_options_ref(); contents.sort_by(|f1, f2| sort_options.compare(f1, f2)); @@ -75,7 +75,7 @@ impl JoshutoDirList { pub fn reload_contents(&mut self, options: &DisplayOption) -> std::io::Result<()> { let filter_func = options.filter_func(); - let mut contents = read_dir_list(self.file_path(), filter_func, options.show_icons())?; + let mut contents = read_dir_list(self.file_path(), filter_func, options)?; let sort_options = options.sort_options_ref(); contents.sort_by(|f1, f2| sort_options.compare(f1, f2)); @@ -174,14 +174,15 @@ impl JoshutoDirList { fn read_dir_list<F>( path: &path::Path, filter_func: F, - show_icons: bool, + options: &DisplayOption, ) -> std::io::Result<Vec<JoshutoDirEntry>> where F: Fn(&Result<fs::DirEntry, std::io::Error>) -> bool, { let results: Vec<JoshutoDirEntry> = fs::read_dir(path)? .filter(filter_func) - .filter_map(|res| JoshutoDirEntry::from(&res.ok()?, show_icons).ok()) + .filter_map(|res| JoshutoDirEntry::from(&res.ok()?, options).ok()) .collect(); + Ok(results) } diff --git a/src/fs/entry.rs b/src/fs/entry.rs index 082a6c0..5875a78 100644 --- a/src/fs/entry.rs +++ b/src/fs/entry.rs @@ -1,9 +1,10 @@ -use std::{fs, path}; +use std::{fs, io, path}; use crate::fs::{FileType, JoshutoMetadata}; #[cfg(feature = "devicons")] use crate::util::devicons::*; +use crate::util::display::DisplayOption; #[derive(Clone, Debug)] pub struct JoshutoDirEntry { @@ -16,46 +17,29 @@ pub struct JoshutoDirEntry { } impl JoshutoDirEntry { - pub fn from(direntry: &fs::DirEntry, show_icons: bool) -> std::io::Result<Self> { + pub fn from(direntry: &fs::DirEntry, options: &DisplayOption) -> io::Result<Self> { let path = direntry.path(); - let metadata = JoshutoMetadata::from(&path)?; - + let mut metadata = JoshutoMetadata::from(&path)?; let name = direntry .file_name() .as_os_str() .to_string_lossy() .to_string(); + if options.automatically_count_files() && metadata.file_type().is_dir() { + if let Ok(size) = get_directory_size(path.as_path()) { + metadata.update_directory_size(size); + } + } + #[cfg(feature = "devicons")] - let label = if show_icons { - let icon = match metadata.file_type() { - FileType::Directory => DIR_NODE_EXACT_MATCHES - .get(name.as_str()) - .cloned() - .unwrap_or(DEFAULT_DIR), - _ => FILE_NODE_EXACT_MATCHES - .get(name.as_str()) - .cloned() - .unwrap_or(match path.extension() { - Some(s) => FILE_NODE_EXTENSIONS - .get(match s.to_str() { - Some(s) => s, - None => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Failed converting OsStr to str", - )) - } - }) - .unwrap_or(&DEFAULT_FILE), - None => DEFAULT_FILE, - }), - }; - format!("{} {}", icon, name) + let label = if options.show_icons() { + create_icon_label(name.as_str(), &metadata) } else { name.clone() }; + #[cfg(not(feature = "devicons"))] let label = name.clone(); @@ -69,6 +53,10 @@ impl JoshutoDirEntry { }) } + pub fn update_label(&mut self, label: String) { + self.label = label; + } + pub fn file_name(&self) -> &str { self.name.as_str() } @@ -128,3 +116,28 @@ impl std::cmp::Ord for JoshutoDirEntry { self.file_path().cmp(other.file_path()) } } + +fn create_icon_label(name: &str, metadata: &JoshutoMetadata) -> String { + let label = { + let icon = + match metadata.file_type() { + FileType::Directory => DIR_NODE_EXACT_MATCHES + .get(name) + .cloned() + .unwrap_or(DEFAULT_DIR), + _ => FILE_NODE_EXACT_MATCHES.get(name).cloned().unwrap_or( + match name.rsplit_once('.') { + Some((_, ext)) => FILE_NODE_EXTENSIONS.get(ext).unwrap_or(&DEFAULT_FILE), + None => DEFAULT_FILE, + }, + ), + }; + format!("{} {}", icon, name) + }; + label +} + +fn get_directory_size(path: &path::Path) -> io::Result<usize> { + let directory_size = fs::read_dir(path).map(|s| s.count()); + directory_size +} diff --git a/src/fs/metadata.rs b/src/fs/metadata.rs index 0035024..52caac2 100644 --- a/src/fs/metadata.rs +++ b/src/fs/metadata.rs @@ -1,11 +1,20 @@ use std::{fs, io, path, time}; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum FileType { Directory, File, } +impl FileType { + pub fn is_dir(&self) -> bool { + *self == Self::Directory + } + pub fn is_file(&self) -> bool { + *self == Self::File + } +} + #[derive(Clone, Debug)] pub enum LinkType { Normal, @@ -45,10 +54,7 @@ impl JoshutoMetadata { }; let (_file_type, _directory_size) = match metadata.as_ref() { - Ok(m) if m.file_type().is_dir() => { - let _directory_size = fs::read_dir(path).map(|s| s.count()).ok(); - (FileType::Directory, _directory_size) - } + Ok(m) if m.file_type().is_dir() => (FileType::Directory, None), _ => (FileType::File, None), }; @@ -98,6 +104,10 @@ impl JoshutoMetadata { self._directory_size } + pub fn update_directory_size(&mut self, size: usize) { + self._directory_size = Some(size); + } + pub fn modified(&self) -> time::SystemTime { self._modified } |