use crate::param::{Param, TargetMode};
use std::{
ffi::OsString,
fs::{self, ReadDir},
path::{Path, PathBuf},
};
pub(crate) fn list_current_dir(param: &Param) -> Vec<PathBuf> {
let rs_data = fs::read_dir(".");
if let Ok(files_and_dirs) = rs_data {
let target_mode = param.get_target_mode();
match target_mode {
TargetMode::File => list_files(param, files_and_dirs),
TargetMode::Dir => list_dirs(param, files_and_dirs),
}
} else {
Vec::new()
}
}
fn list_files(param: &Param, files_and_dirs: ReadDir) -> Vec<PathBuf> {
list_entry(param, FileChecker::new_checker(), files_and_dirs)
}
fn list_dirs(param: &Param, files_and_dirs: ReadDir) -> Vec<PathBuf> {
list_entry(param, DirChecker::new_checker(), files_and_dirs)
}
fn list_entry(
param: &Param,
checker: Box<dyn DirEntryChecker>,
files_and_dirs: ReadDir,
) -> Vec<PathBuf> {
let from_regex = param.get_from_regex();
files_and_dirs
.filter_map(|x| x.ok())
.filter(|entry| {
let name = entry.file_name();
checker.check(&name) &&
name.to_str()
.map(|s| from_regex.is_match(s))
.unwrap_or(false)
})
.map(|x| x.path())
.collect()
}
trait DirEntryChecker {
fn check(&self, name: &OsString) -> bool;
}
struct DirChecker {}
impl DirChecker {
fn new_checker() -> Box<dyn DirEntryChecker> {
Box::new(Self {})
}
}
impl DirEntryChecker for DirChecker {
fn check(&self, name: &OsString) -> bool {
Path::new(name).is_dir()
}
}
struct FileChecker {}
impl FileChecker {
fn new_checker() -> Box<dyn DirEntryChecker> {
Box::new(Self {})
}
}
impl DirEntryChecker for FileChecker {
fn check(&self, name: &OsString) -> bool {
Path::new(name).is_file()
}
}