summaryrefslogtreecommitdiffstats
path: root/src/fs
diff options
context:
space:
mode:
authorJeff Zhao <jeff.no.zhao@gmail.com>2021-07-22 22:29:14 -0400
committerJeff Zhao <jeff.no.zhao@gmail.com>2021-07-22 22:32:14 -0400
commit97ca1fb6d44de66d872422783c38ae198b0edfb9 (patch)
tree695eacc8aaeda28f32fd839169fb8862caf09571 /src/fs
parent4385f6eb523ece963b154f2525f82e8e9f3882f1 (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.rs11
-rw-r--r--src/fs/entry.rs71
-rw-r--r--src/fs/metadata.rs20
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
}