use crate::options::OptionsError;
use crate::fs::dir_action::{DirAction, RecurseOptions};
use clap::ArgMatches;
impl DirAction {
pub fn deduce(
matches: &ArgMatches,
can_tree: bool,
strict: bool,
) -> Result<Self, OptionsError> {
let recurse = matches.get_flag("recurse");
let as_file = matches.get_flag("treat-dirs-as-files");
let tree = matches.get_flag("tree");
if strict {
if !recurse && !tree && matches.get_one::<usize>("level").is_some() {
return Err(OptionsError::Useless2("level", "recurse", "tree"));
} else if recurse && as_file {
return Err(OptionsError::Conflict("recurse", "treat-dirs-as-files"));
} else if tree && as_file {
return Err(OptionsError::Conflict("tree", "treat-dirs-as-files"));
}
}
if tree && can_tree {
Ok(Self::Recurse(RecurseOptions::deduce(matches, true)))
} else if recurse {
Ok(Self::Recurse(RecurseOptions::deduce(matches, false)))
} else if as_file {
Ok(Self::AsFile)
} else {
Ok(Self::List)
}
}
}
impl RecurseOptions {
pub fn deduce(matches: &ArgMatches, tree: bool) -> Self {
Self {
tree,
max_depth: matches.get_one("level").copied(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::options::parser::test::{mock_cli, mock_cli_try};
#[test]
fn deduce_dir_action_list() {
assert_eq!(
DirAction::deduce(&mock_cli(vec![""]), false, false),
Ok(DirAction::List)
);
}
#[test]
fn deduce_recurse_options_level() {
assert_eq!(
RecurseOptions::deduce(&mock_cli(vec!["--level", "3"]), false),
RecurseOptions {
tree: false,
max_depth: Some(3),
}
);
}
#[test]
fn deduce_recurse_options_no_level() {
assert_eq!(
DirAction::deduce(&mock_cli(vec!["--recurse"]), true, true),
Ok(DirAction::Recurse(RecurseOptions {
tree: false,
max_depth: None,
}))
);
}
#[test]
fn deduce_dir_action_as_file() {
assert_eq!(
DirAction::deduce(&mock_cli(vec!["--treat-dirs-as-files"]), false, false),
Ok(DirAction::AsFile)
);
}
#[test]
fn deduce_dir_action_recurse() {
assert_eq!(
DirAction::deduce(&mock_cli(vec!["--recurse"]), false, false),
Ok(DirAction::Recurse(RecurseOptions {
tree: false,
max_depth: None,
}))
);
}
#[test]
fn deduce_dir_action_tree() {
assert_eq!(
DirAction::deduce(&mock_cli(vec!["--tree"]), true, false),
Ok(DirAction::Recurse(RecurseOptions {
tree: true,
max_depth: None,
}))
);
}
#[test]
fn deduce_dir_action_tree_level() {
assert_eq!(
DirAction::deduce(&mock_cli(vec!["--tree", "--level", "3"]), true, false),
Ok(DirAction::Recurse(RecurseOptions {
tree: true,
max_depth: Some(3),
}))
);
}
#[test]
fn deduce_dir_action_tree_level_conflict() {
assert_eq!(
DirAction::deduce(&mock_cli(vec!["--level", "3"]), false, true),
Err(OptionsError::Useless2("level", "recurse", "tree"))
);
}
#[test]
fn deduce_dir_action_recurse_as_file_conflict() {
assert!(mock_cli_try(vec!["--recurse", "--treat-dirs-as-files"]).is_err());
}
#[test]
fn deduce_dir_action_tree_as_file_conflict() {
assert!(mock_cli_try(vec!["--tree", "--treat-dirs-as-files"]).is_err());
}
}