added a total-size flag, that calculates the total size of directories recursively

This commit is contained in:
Philipp Mildenberger 2019-06-16 20:48:35 +02:00 committed by Abin Simon
parent 3facd44840
commit 744efce1b8
5 changed files with 80 additions and 1 deletions

View file

@ -124,6 +124,12 @@ pub fn build() -> App<'static, 'static> {
.number_of_values(1)
.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")

View file

@ -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
}

View file

@ -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,
}
}
}

View file

@ -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

View file

@ -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
}