strut_config/scanner/
entry.rs1use crate::scanner::dir::ConfigDir;
2use crate::ConfigFile;
3use std::path::PathBuf;
4use strut_core::AppProfile;
5
6#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
8pub enum ConfigEntry {
9 Directory(ConfigDir),
11
12 File(ConfigFile),
14}
15
16impl ConfigEntry {
17 pub fn dir(path: PathBuf) -> Self {
22 Self::Directory(ConfigDir::at(path))
23 }
24
25 pub fn try_from(path: PathBuf) -> Option<Self> {
28 Self::try_from_with_profile(path, None)
29 }
30
31 pub fn try_from_with_profile(path: PathBuf, known_profile: Option<&str>) -> Option<Self> {
35 if path.is_dir() {
37 let config_dir = ConfigDir::make_with_profile(path, known_profile);
38 return Some(ConfigEntry::Directory(config_dir));
39 }
40
41 if let Some(config_file) = ConfigFile::try_make_with_profile(path, known_profile) {
43 return Some(ConfigEntry::File(config_file));
44 }
45
46 None
47 }
48}
49
50impl ConfigEntry {
51 pub fn is_directory(&self) -> bool {
54 matches!(self, ConfigEntry::Directory(_))
55 }
56
57 pub fn is_file(&self) -> bool {
60 matches!(self, ConfigEntry::File(_))
61 }
62
63 pub fn path(&self) -> &PathBuf {
65 match *self {
66 ConfigEntry::Directory(ref config_dir) => config_dir.path(),
67 ConfigEntry::File(ref config_file) => config_file.path(),
68 }
69 }
70
71 pub fn name(&self) -> Option<&str> {
73 self.path().file_name().and_then(std::ffi::OsStr::to_str)
74 }
75
76 pub fn applies_to_active_profile(&self) -> bool {
79 self.applies_to(AppProfile::active())
80 }
81
82 pub fn applies_to(&self, profile: impl AsRef<AppProfile>) -> bool {
88 match *self {
89 ConfigEntry::Directory(ref config_dir) => config_dir.applies_to(profile),
90 ConfigEntry::File(ref config_file) => config_file.applies_to(profile),
91 }
92 }
93
94 pub fn to_config_file(self) -> Option<ConfigFile> {
96 match self {
97 ConfigEntry::Directory(_) => None,
98 ConfigEntry::File(config_file) => Some(config_file),
99 }
100 }
101}
102
103impl ConfigEntry {
104 pub fn cd(self) -> ConfigEntryIter {
118 match self {
119 ConfigEntry::Directory(ref config_dir) => {
120 let config_entries = config_dir.expand(config_dir.profile());
121 ConfigEntryIter::Directory(config_entries.into_iter())
122 }
123 ConfigEntry::File(_) => ConfigEntryIter::File(std::iter::once(self)),
124 }
125 }
126
127 pub fn cd_capturing_profile(self) -> ConfigEntryIter {
131 match self {
132 ConfigEntry::Directory(ref config_dir) => {
133 let config_entries = config_dir.expand(config_dir.name());
134 ConfigEntryIter::Directory(config_entries.into_iter())
135 }
136 ConfigEntry::File(_) => ConfigEntryIter::File(std::iter::once(self)),
137 }
138 }
139
140 pub fn cd_forgetting_profile(self) -> ConfigEntryIter {
145 match self {
146 ConfigEntry::Directory(ref config_dir) => {
147 let config_entries = config_dir.expand(None);
148 ConfigEntryIter::Directory(config_entries.into_iter())
149 }
150 ConfigEntry::File(_) => ConfigEntryIter::File(std::iter::once(self)),
151 }
152 }
153}
154
155impl From<ConfigEntry> for PathBuf {
156 fn from(file: ConfigEntry) -> Self {
157 match file {
158 ConfigEntry::Directory(config_dir) => PathBuf::from(config_dir),
159 ConfigEntry::File(config_file) => PathBuf::from(config_file),
160 }
161 }
162}
163
164pub enum ConfigEntryIter {
166 Directory(std::vec::IntoIter<ConfigEntry>),
169
170 File(std::iter::Once<ConfigEntry>),
172}
173
174impl Iterator for ConfigEntryIter {
175 type Item = ConfigEntry;
176
177 fn next(&mut self) -> Option<Self::Item> {
178 match *self {
179 Self::Directory(ref mut iter) => iter.next(),
180 Self::File(ref mut iter) => iter.next(),
181 }
182 }
183
184 fn size_hint(&self) -> (usize, Option<usize>) {
185 match *self {
186 Self::Directory(ref iter) => iter.size_hint(),
187 Self::File(ref iter) => iter.size_hint(),
188 }
189 }
190}