Add a depth parameter for the -R and --tree options

This commit is contained in:
Max Taldykin 2018-12-19 21:00:21 +03:00 committed by Pierre Peltier
parent 115e9f5036
commit c74b5d619e
5 changed files with 77 additions and 9 deletions

View file

@ -58,14 +58,23 @@ pub fn build() -> App<'static, 'static> {
.short("R")
.long("recursive")
.multiple(true)
.conflicts_with("tree")
.help("Recurse into directories"),
)
.arg(
Arg::with_name("tree")
.long("tree")
.multiple(true)
.conflicts_with("recursive")
.help("Recurse into directories and present the result as a tree"),
)
.arg(
Arg::with_name("depth")
.long("depth")
.takes_value(true)
.value_name("NUM")
.help("Stop recursing into directories after reaching specified depth"),
)
.arg(
Arg::with_name("date")
.long("date")

View file

@ -56,6 +56,10 @@ impl Core {
}
fn run_inner(&self, paths: Vec<PathBuf>, depth: usize) {
if depth > self.flags.recursion_depth {
return;
}
let mut dirs = Vec::new();
let mut files = Vec::new();
@ -101,7 +105,7 @@ impl Core {
})
.collect();
self.run_inner(folder_dirs, depth);
self.run_inner(folder_dirs, depth + 1);
} else {
self.display
.print_outputs(self.get_batch_outputs(&folder_batch));

View file

@ -1,4 +1,4 @@
use clap::ArgMatches;
use clap::{ArgMatches, Error, ErrorKind};
#[derive(Clone, Debug, Copy)]
pub struct Flags {
@ -13,10 +13,11 @@ pub struct Flags {
pub date: DateFlag,
pub color: WhenFlag,
pub icon: WhenFlag,
pub recursion_depth: usize,
}
impl<'a> From<ArgMatches<'a>> for Flags {
fn from(matches: ArgMatches) -> Self {
impl Flags {
pub fn from_matches(matches: &ArgMatches) -> Result<Self, Error> {
let color_inputs: Vec<&str> = matches.values_of("color").unwrap().collect();
let icon_inputs: Vec<&str> = matches.values_of("icon").unwrap().collect();
let date_inputs: Vec<&str> = matches.values_of("date").unwrap().collect();
@ -32,20 +33,42 @@ impl<'a> From<ArgMatches<'a>> for Flags {
SortOrder::Default
};
Self {
let display_tree = matches.is_present("tree");
let recursive = matches.is_present("recursive");
let recursion_depth = match matches.value_of("depth") {
Some(str) if recursive || display_tree => match str.parse::<usize>() {
Ok(val) => val,
Err(_) => {
return Err(Error::with_description(
"The argument '--depth' requires a valid number",
ErrorKind::ValueValidation,
))
}
},
Some(_) => {
return Err(Error::with_description(
"The argument '--depth' requires '--tree' or '--recursive'",
ErrorKind::MissingRequiredArgument,
))
}
None => usize::max_value(),
};
Ok(Self {
display_all: matches.is_present("all"),
display_long: matches.is_present("long"),
display_online: matches.is_present("oneline"),
display_tree: matches.is_present("tree"),
display_tree,
display_indicators: matches.is_present("indicators"),
recursive: matches.is_present("recursive"),
recursive,
recursion_depth,
sort_by,
sort_order,
// Take only the last value
date: DateFlag::from(date_inputs[date_inputs.len() - 1]),
color: WhenFlag::from(color_inputs[color_inputs.len() - 1]),
icon: WhenFlag::from(icon_inputs[icon_inputs.len() - 1]),
}
})
}
}
@ -58,6 +81,7 @@ impl Default for Flags {
display_tree: false,
display_indicators: false,
recursive: false,
recursion_depth: usize::max_value(),
sort_by: SortFlag::Name,
sort_order: SortOrder::Default,
date: DateFlag::Date,
@ -112,3 +136,32 @@ pub enum SortOrder {
Default,
Reverse,
}
#[cfg(test)]
mod test {
use super::Flags;
use crate::app;
use clap::ErrorKind;
#[test]
fn test_validate_depth_value() {
let matches = app::build()
.get_matches_from_safe(vec!["lsd", "--tree", "--depth", "xx"])
.unwrap();
let res = Flags::from_matches(&matches);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind, ErrorKind::ValueValidation);
}
#[test]
fn test_useless_depth() {
let matches = app::build()
.get_matches_from_safe(vec!["lsd", "--depth", "10"])
.unwrap();
let res = Flags::from_matches(&matches);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
}
}

View file

@ -40,7 +40,8 @@ fn main() {
.map(PathBuf::from)
.collect();
let core = Core::new(Flags::from(matches));
let flags = Flags::from_matches(&matches).unwrap_or_else(|err| err.exit());
let core = Core::new(flags);
core.run(inputs);
}

View file

@ -76,6 +76,7 @@ mod test {
display_tree: true,
display_indicators: true,
recursive: true,
recursion_depth: usize::max_value(),
sort_by: SortFlag::Name,
sort_order: SortOrder::Default,
date: DateFlag::Relative,