aboutsummaryrefslogtreecommitdiff
path: root/arg_picker/src/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'arg_picker/src/builtin')
-rw-r--r--arg_picker/src/builtin/pick_paths.rs167
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);
+ }
+ }
+ }
+}