summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Mildenberger <philipp.mildenberger@student.uibk.ac.at>2019-06-16 20:48:35 +0200
committerAbin Simon <abinsimon10@gmail.com>2019-07-17 10:27:59 +0000
commit744efce1b8d85966a8740d6fe5416b9d459b89ca (patch)
tree2e7b3b7f7dd7787a7d4f0b2fc16fb42fb5ef9f59
parent3facd4484083003e73978a3de688529586c8021f (diff)
added a total-size flag, that calculates the total size of directories recursively
-rw-r--r--src/app.rs6
-rw-r--r--src/core.rs5
-rw-r--r--src/flags.rs4
-rw-r--r--src/meta/mod.rs62
-rw-r--r--src/meta/size.rs4
5 files changed, 80 insertions, 1 deletions
diff --git a/src/app.rs b/src/app.rs
index cd6709f..c386265 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -125,6 +125,12 @@ pub fn build() -> App<'static, 'static> {
.help("How to display size"),
)
.arg(
+ Arg::with_name("total-size")
+ .long("total-size")
+ .multiple(true)
+ .help("Display the total size of directories"),
+ )
+ .arg(
Arg::with_name("date")
.long("date")
.possible_value("date")
diff --git a/src/core.rs b/src/core.rs
index 8240ef8..74aaf89 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -116,6 +116,11 @@ impl Core {
}
};
}
+ if self.flags.total_size {
+ for meta in &mut meta_list.iter_mut() {
+ meta.calculate_total_size();
+ }
+ }
meta_list
}
diff --git a/src/flags.rs b/src/flags.rs
index bb22a4e..790b554 100644
--- a/src/flags.rs
+++ b/src/flags.rs
@@ -17,6 +17,7 @@ pub struct Flags {
pub recursion_depth: usize,
pub blocks: Vec<Block>,
pub no_symlink: bool,
+ pub total_size: bool,
}
impl Flags {
@@ -91,6 +92,7 @@ impl Flags {
None => usize::max_value(),
};
let no_symlink = matches.is_present("no-symlink");
+ let total_size = matches.is_present("total-size");
Ok(Self {
display,
@@ -125,6 +127,7 @@ impl Flags {
DirOrderFlag::from(dir_order_inputs[dir_order_inputs.len() - 1])
},
no_symlink,
+ total_size,
})
}
}
@@ -154,6 +157,7 @@ impl Default for Flags {
Block::Name,
],
no_symlink: false,
+ total_size: false,
}
}
}
diff --git a/src/meta/mod.rs b/src/meta/mod.rs
index 6f77282..11bcdee 100644
--- a/src/meta/mod.rs
+++ b/src/meta/mod.rs
@@ -101,7 +101,7 @@ impl Meta {
}
}
- let mut entry_meta = match Self::from_path(&path.to_path_buf()) {
+ let mut entry_meta = match Self::from_path(&path) {
Ok(res) => res,
Err(err) => {
eprintln!("cannot access '{}': {}", path.display(), err);
@@ -123,6 +123,66 @@ impl Meta {
Ok(Some(content))
}
+ pub fn calculate_total_size(&mut self) {
+ if let FileType::Directory{ uid: _ } = self.file_type {
+ if let Some(metas) = &mut self.content {
+ let mut size_accumulated = self.size.get_bytes();
+ for x in &mut metas.iter_mut() {
+ x.calculate_total_size();
+ size_accumulated += x.size.get_bytes();
+ }
+ self.size = Size::new(size_accumulated);
+ } else { // possibility that 'depth' limited the recursion in 'recurse_into'
+ self.size = Size::new(Meta::calculate_total_file_size(&self.path));
+ }
+ }
+ }
+
+ fn calculate_total_file_size(path: &PathBuf) -> u64 {
+ let metadata = if read_link(&path).is_ok() {
+ // If the file is a link, retrieve the metadata without following
+ // the link.
+ path.symlink_metadata()
+ } else {
+ path.metadata()
+ };
+ let metadata = match metadata {
+ Ok(meta) => meta,
+ Err(err) => {
+ eprintln!("cannot access '{}': {}", path.display(), err);
+ return 0;
+ }
+ };
+ let file_type = metadata.file_type();
+ if file_type.is_file() {
+ metadata.len()
+ } else if file_type.is_dir() {
+ let mut size = metadata.len();
+
+ let entries = match path.read_dir() {
+ Ok(entries) => entries,
+ Err(err) => {
+ eprintln!("cannot access '{}': {}", path.display(), err);
+ return size;
+ }
+ };
+ for entry in entries {
+ let path = match entry {
+ Ok(entry) => entry.path(),
+ Err(err) => {
+ eprintln!("cannot access '{}': {}", path.display(), err);
+ continue;
+ }
+ };
+ size += Meta::calculate_total_file_size(&path);
+ }
+ size
+ }
+ else {
+ 0
+ }
+ }
+
pub fn from_path(path: &PathBuf) -> Result<Self, std::io::Error> {
let metadata = if read_link(path).is_ok() {
// If the file is a link, retrieve the metadata without following
diff --git a/src/meta/size.rs b/src/meta/size.rs
index e78e282..63ad688 100644
--- a/src/meta/size.rs
+++ b/src/meta/size.rs
@@ -25,6 +25,10 @@ impl<'a> From<&'a Metadata> for Size {
}
impl Size {
+ pub fn new(bytes: u64) -> Self {
+ Self { bytes: bytes }
+ }
+
pub fn get_bytes(&self) -> u64 {
self.bytes
}