diff options
Diffstat (limited to 'arg_picker/src/builtin/pick_paths.rs')
| -rw-r--r-- | arg_picker/src/builtin/pick_paths.rs | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/arg_picker/src/builtin/pick_paths.rs b/arg_picker/src/builtin/pick_paths.rs new file mode 100644 index 0000000..8e6c0fd --- /dev/null +++ b/arg_picker/src/builtin/pick_paths.rs @@ -0,0 +1,167 @@ +use std::{ + fs, + path::{Path, PathBuf}, +}; + +use crate::{ + PickerArgResult::{self, NotFound, Parsed, Unparsed}, + SinglePickable, + value::{ + DirPath, FilePath, NoDirPath, NoFilePath, NoPath, NoSymlinkPath, RecursiveFiles, + SymlinkPath, + }, +}; + +impl SinglePickable for FilePath { + fn pick_single(str: Option<&str>) -> PickerArgResult<Self> { + match <PathBuf as SinglePickable>::pick_single(str) { + Parsed(path) => { + if path.exists() && path.is_file() { + Parsed(FilePath::from(path)) + } else { + NotFound + } + } + Unparsed => Unparsed, + NotFound => NotFound, + } + } +} + +impl SinglePickable for NoFilePath { + fn pick_single(str: Option<&str>) -> PickerArgResult<Self> { + match <PathBuf as SinglePickable>::pick_single(str) { + Parsed(path) => { + if !path.exists() || !path.is_file() { + Parsed(NoFilePath::from(path)) + } else { + NotFound + } + } + Unparsed => Unparsed, + NotFound => NotFound, + } + } +} + +impl SinglePickable for DirPath { + fn pick_single(str: Option<&str>) -> PickerArgResult<Self> { + match <PathBuf as SinglePickable>::pick_single(str) { + Parsed(path) => { + if path.exists() && path.is_dir() { + Parsed(DirPath::from(path)) + } else { + NotFound + } + } + Unparsed => Unparsed, + NotFound => NotFound, + } + } +} + +impl SinglePickable for NoDirPath { + fn pick_single(str: Option<&str>) -> PickerArgResult<Self> { + match <PathBuf as SinglePickable>::pick_single(str) { + Parsed(path) => { + if !path.exists() || !path.is_dir() { + Parsed(NoDirPath::from(path)) + } else { + NotFound + } + } + Unparsed => Unparsed, + NotFound => NotFound, + } + } +} + +impl SinglePickable for SymlinkPath { + fn pick_single(str: Option<&str>) -> PickerArgResult<Self> { + match <PathBuf as SinglePickable>::pick_single(str) { + Parsed(path) => { + if path.exists() && path.is_symlink() { + Parsed(SymlinkPath::from(path)) + } else { + NotFound + } + } + Unparsed => Unparsed, + NotFound => NotFound, + } + } +} + +impl SinglePickable for NoSymlinkPath { + fn pick_single(str: Option<&str>) -> PickerArgResult<Self> { + match <PathBuf as SinglePickable>::pick_single(str) { + Parsed(path) => { + if !path.exists() || !path.is_symlink() { + Parsed(NoSymlinkPath::from(path)) + } else { + NotFound + } + } + Unparsed => Unparsed, + NotFound => NotFound, + } + } +} + +impl SinglePickable for NoPath { + fn pick_single(str: Option<&str>) -> PickerArgResult<Self> { + match <PathBuf as SinglePickable>::pick_single(str) { + Parsed(path) => { + if !path.exists() { + Parsed(NoPath::from(path)) + } else { + NotFound + } + } + Unparsed => Unparsed, + NotFound => NotFound, + } + } +} + +impl SinglePickable for RecursiveFiles { + fn pick_single(str: Option<&str>) -> PickerArgResult<Self> { + match <PathBuf as SinglePickable>::pick_single(str) { + Parsed(path) => { + if !path.exists() { + return NotFound; + } + if path.is_file() || path.is_symlink() { + return Parsed(RecursiveFiles::from(vec![path])); + } + let mut entries = Vec::new(); + if let Ok(dir_entries) = fs::read_dir(&path) { + for entry in dir_entries.flatten() { + let entry_path = entry.path(); + if entry_path.is_file() || entry_path.is_symlink() { + entries.push(entry_path); + } else if entry_path.is_dir() { + collect_files(&entry_path, &mut entries); + } + } + } + Parsed(RecursiveFiles::from(entries)) + } + Unparsed => Unparsed, + NotFound => NotFound, + } + } +} + +fn collect_files(dir: &Path, entries: &mut Vec<PathBuf>) { + if let Ok(dir_entries) = fs::read_dir(dir) { + for entry in dir_entries.flatten() { + let entry_path = entry.path(); + if entry_path.is_file() || entry_path.is_symlink() { + entries.push(entry_path); + } else if entry_path.is_dir() { + collect_files(&entry_path, entries); + } + } + } +} |
