mirror of
https://github.com/lsd-rs/lsd
synced 2025-03-05 07:27:20 +00:00
added a total-size flag, that calculates the total size of directories recursively
This commit is contained in:
parent
3facd44840
commit
744efce1b8
5 changed files with 80 additions and 1 deletions
|
@ -124,6 +124,12 @@ pub fn build() -> App<'static, 'static> {
|
||||||
.number_of_values(1)
|
.number_of_values(1)
|
||||||
.help("How to display size"),
|
.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(
|
||||||
Arg::with_name("date")
|
Arg::with_name("date")
|
||||||
.long("date")
|
.long("date")
|
||||||
|
|
|
@ -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
|
meta_list
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub struct Flags {
|
||||||
pub recursion_depth: usize,
|
pub recursion_depth: usize,
|
||||||
pub blocks: Vec<Block>,
|
pub blocks: Vec<Block>,
|
||||||
pub no_symlink: bool,
|
pub no_symlink: bool,
|
||||||
|
pub total_size: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Flags {
|
impl Flags {
|
||||||
|
@ -91,6 +92,7 @@ impl Flags {
|
||||||
None => usize::max_value(),
|
None => usize::max_value(),
|
||||||
};
|
};
|
||||||
let no_symlink = matches.is_present("no-symlink");
|
let no_symlink = matches.is_present("no-symlink");
|
||||||
|
let total_size = matches.is_present("total-size");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
display,
|
display,
|
||||||
|
@ -125,6 +127,7 @@ impl Flags {
|
||||||
DirOrderFlag::from(dir_order_inputs[dir_order_inputs.len() - 1])
|
DirOrderFlag::from(dir_order_inputs[dir_order_inputs.len() - 1])
|
||||||
},
|
},
|
||||||
no_symlink,
|
no_symlink,
|
||||||
|
total_size,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,6 +157,7 @@ impl Default for Flags {
|
||||||
Block::Name,
|
Block::Name,
|
||||||
],
|
],
|
||||||
no_symlink: false,
|
no_symlink: false,
|
||||||
|
total_size: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
Ok(res) => res,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("cannot access '{}': {}", path.display(), err);
|
eprintln!("cannot access '{}': {}", path.display(), err);
|
||||||
|
@ -123,6 +123,66 @@ impl Meta {
|
||||||
Ok(Some(content))
|
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> {
|
pub fn from_path(path: &PathBuf) -> Result<Self, std::io::Error> {
|
||||||
let metadata = if read_link(path).is_ok() {
|
let metadata = if read_link(path).is_ok() {
|
||||||
// If the file is a link, retrieve the metadata without following
|
// If the file is a link, retrieve the metadata without following
|
||||||
|
|
|
@ -25,6 +25,10 @@ impl<'a> From<&'a Metadata> for Size {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Size {
|
impl Size {
|
||||||
|
pub fn new(bytes: u64) -> Self {
|
||||||
|
Self { bytes: bytes }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_bytes(&self) -> u64 {
|
pub fn get_bytes(&self) -> u64 {
|
||||||
self.bytes
|
self.bytes
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue