rrn 0.1.3

batch rename files/dirs by regex
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(|x| x.is_ok())
        .filter(|x| {
            let name = &x.as_ref().unwrap().file_name();
            checker.check(name) && from_regex.is_match(name.to_str().unwrap())
        })
        .map(|x| x.unwrap().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()
    }
}