file_matcher/entries/
many.rs

1use crate::utils::is_readable_entry;
2use crate::{EntryName, EntryType, Result};
3use std::fmt::Debug;
4use std::path::PathBuf;
5
6pub trait ManyEntriesNamed: Debug {
7    fn within_path_buf(&self, directory: PathBuf) -> ManyEntries;
8    fn entry_name(&self) -> &EntryName;
9    fn entry_type(&self) -> &EntryType;
10    fn name_alias(&self) -> Option<&str>;
11    fn boxed(&self) -> Box<dyn ManyEntriesNamed>;
12}
13
14#[derive(Debug)]
15pub struct ManyEntries {
16    entries_named: Box<dyn ManyEntriesNamed>,
17    directory: PathBuf,
18}
19
20impl ManyEntries {
21    pub fn new(entries_named: Box<dyn ManyEntriesNamed>, directory: impl Into<PathBuf>) -> Self {
22        Self {
23            entries_named,
24            directory: directory.into(),
25        }
26    }
27
28    pub fn find(&self) -> Result<Vec<PathBuf>> {
29        let entry_type = self.entries_named.entry_type();
30        let entry_name = self.entries_named.entry_name();
31
32        self.find_by_type_and_name(entry_type, entry_name)
33    }
34
35    fn find_by_type_and_name(
36        &self,
37        entry_type: &EntryType,
38        entry_name: &EntryName,
39    ) -> Result<Vec<PathBuf>> {
40        match entry_name {
41            EntryName::Exact(name) => {
42                let entry = self.directory.join(name);
43                if is_readable_entry(entry_type, &entry) {
44                    Ok(vec![entry])
45                } else {
46                    Ok(vec![])
47                }
48            }
49            EntryName::Any(names) => {
50                let entries = names
51                    .iter()
52                    .map(|each| self.directory.join(each))
53                    .filter(|each| is_readable_entry(entry_type, each.as_path()))
54                    .collect::<Vec<PathBuf>>();
55
56                Ok(entries)
57            }
58            EntryName::AnyNamed(entry_names) => {
59                let mut entries: Vec<PathBuf> = vec![];
60
61                for entry_name in entry_names {
62                    for each_path in self.find_by_type_and_name(entry_type, entry_name)? {
63                        entries.push(each_path);
64                    }
65                }
66
67                Ok(entries)
68            }
69            #[cfg(feature = "regex")]
70            EntryName::Regex(regex_pattern) => {
71                let entries = crate::finders::regex_finder::find_entries_in_directory_matching(
72                    entry_type,
73                    regex_pattern,
74                    &self.directory,
75                )?;
76                Ok(entries)
77            }
78            #[cfg(feature = "wildmatch")]
79            EntryName::Wildmatch(wildmatch_pattern) => {
80                let entries = crate::finders::wildmatch_finder::find_entries_in_directory_matching(
81                    entry_type,
82                    wildmatch_pattern,
83                    &self.directory,
84                )?;
85                Ok(entries)
86            }
87        }
88    }
89}
90
91impl Clone for ManyEntries {
92    fn clone(&self) -> Self {
93        Self::new(self.entries_named.boxed(), self.directory.clone())
94    }
95}