rs_path_filter_cel/
lib.rs1use cel::Value;
2use cel::objects::{Key, Map};
3use std::collections::HashMap;
4use std::path::PathBuf;
5use std::sync::Arc;
6
7pub struct PathInfo {
8 full_path: PathBuf,
9}
10
11impl From<&str> for PathInfo {
12 fn from(s: &str) -> Self {
13 let path = PathBuf::from(s);
14 PathInfo { full_path: path }
15 }
16}
17
18impl From<PathInfo> for Value {
19 fn from(path_info: PathInfo) -> Self {
20 let mut map = Map {
21 map: Arc::new(HashMap::new()),
22 };
23
24 let path = &path_info.full_path;
25
26 if let Some(internal_map) = Arc::get_mut(&mut map.map) {
27 let ext = path
28 .extension()
29 .and_then(|s| s.to_str())
30 .unwrap_or("")
31 .to_string();
32 internal_map.insert(
33 Key::String(Arc::new("ext".to_string())),
34 Value::String(ext.into()),
35 );
36
37 if let Some(file_name) = path.file_name().and_then(|os_str| os_str.to_str()) {
38 internal_map.insert(
39 Key::String(Arc::new("basename".to_string())),
40 Value::String(file_name.to_string().into()),
41 );
42 }
43 if let Some(parent) = path.parent().and_then(|p| p.to_str()) {
44 internal_map.insert(
45 Key::String(Arc::new("parent".to_string())),
46 Value::String(parent.to_string().into()),
47 );
48 }
49 if let Some(file_stem) = path.file_stem().and_then(|os_str| os_str.to_str()) {
50 internal_map.insert(
51 Key::String(Arc::new("file_stem".to_string())),
52 Value::String(file_stem.to_string().into()),
53 );
54 }
55 }
56
57 Value::Map(map)
58 }
59}
60
61#[cfg(test)]
62#[allow(clippy::panic)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_path_info_from_str() {
68 let path_str = "dir1/dir2/file.txt";
69 let path_info = PathInfo::from(path_str);
70 assert_eq!(path_info.full_path, PathBuf::from(path_str));
71
72 let cel_value: Value = path_info.into();
73 if let Value::Map(map) = cel_value {
74 let internal_map = map.map.as_ref();
76 assert_eq!(
77 internal_map.get(&Key::String(Arc::new("ext".to_string()))),
78 Some(&Value::String("txt".to_string().into()))
79 );
80 assert_eq!(
81 internal_map.get(&Key::String(Arc::new("basename".to_string()))),
82 Some(&Value::String("file.txt".to_string().into()))
83 );
84 assert_eq!(
85 internal_map.get(&Key::String(Arc::new("parent".to_string()))),
86 Some(&Value::String("dir1/dir2".to_string().into()))
87 );
88 assert_eq!(
89 internal_map.get(&Key::String(Arc::new("file_stem".to_string()))),
90 Some(&Value::String("file".to_string().into()))
91 );
92 } else {
93 panic!("Expected a CEL Map Value");
94 }
95 }
96
97 #[test]
98 fn test_path_info_root_path() {
99 let path_str = "/root/file.ext";
100 let path_info = PathInfo::from(path_str);
101 let cel_value: Value = path_info.into();
102 if let Value::Map(map) = cel_value {
103 let internal_map = map.map.as_ref();
104 assert_eq!(
105 internal_map.get(&Key::String(Arc::new("ext".to_string()))),
106 Some(&Value::String("ext".to_string().into()))
107 );
108 assert_eq!(
109 internal_map.get(&Key::String(Arc::new("basename".to_string()))),
110 Some(&Value::String("file.ext".to_string().into()))
111 );
112 assert_eq!(
113 internal_map.get(&Key::String(Arc::new("parent".to_string()))),
114 Some(&Value::String("/root".to_string().into()))
115 );
116 assert_eq!(
117 internal_map.get(&Key::String(Arc::new("file_stem".to_string()))),
118 Some(&Value::String("file".to_string().into()))
119 );
120 } else {
121 panic!("Expected a CEL Map Value");
122 }
123 }
124
125 #[test]
126 fn test_path_info_no_extension() {
127 let path_str = "dir/filename_no_ext";
128 let path_info = PathInfo::from(path_str);
129 let cel_value: Value = path_info.into();
130 if let Value::Map(map) = cel_value {
131 let internal_map = map.map.as_ref();
132 assert_eq!(
133 internal_map.get(&Key::String(Arc::new("ext".to_string()))),
134 Some(&Value::String("".to_string().into()))
135 );
136 assert_eq!(
137 internal_map.get(&Key::String(Arc::new("basename".to_string()))),
138 Some(&Value::String("filename_no_ext".to_string().into()))
139 );
140 assert_eq!(
141 internal_map.get(&Key::String(Arc::new("parent".to_string()))),
142 Some(&Value::String("dir".to_string().into()))
143 );
144 assert_eq!(
145 internal_map.get(&Key::String(Arc::new("file_stem".to_string()))),
146 Some(&Value::String("filename_no_ext".to_string().into()))
147 );
148 } else {
149 panic!("Expected a CEL Map Value");
150 }
151 }
152
153 #[test]
154 fn test_path_info_only_filename() {
155 let path_str = "file.csv";
156 let path_info = PathInfo::from(path_str);
157 let cel_value: Value = path_info.into();
158 if let Value::Map(map) = cel_value {
159 let internal_map = map.map.as_ref();
160 assert_eq!(
161 internal_map.get(&Key::String(Arc::new("ext".to_string()))),
162 Some(&Value::String("csv".to_string().into()))
163 );
164 assert_eq!(
165 internal_map.get(&Key::String(Arc::new("basename".to_string()))),
166 Some(&Value::String("file.csv".to_string().into()))
167 );
168 assert_eq!(
169 internal_map.get(&Key::String(Arc::new("parent".to_string()))),
170 Some(&Value::String("".to_string().into()))
171 );
172 assert_eq!(
173 internal_map.get(&Key::String(Arc::new("file_stem".to_string()))),
174 Some(&Value::String("file".to_string().into()))
175 );
176 } else {
177 panic!("Expected a CEL Map Value");
178 }
179 }
180
181 #[test]
182 fn test_path_info_dotfile() {
183 let path_str = ".config";
184 let path_info = PathInfo::from(path_str);
185 let cel_value: Value = path_info.into();
186 if let Value::Map(map) = cel_value {
187 let internal_map = map.map.as_ref();
188 assert_eq!(
189 internal_map.get(&Key::String(Arc::new("ext".to_string()))),
190 Some(&Value::String("".to_string().into()))
191 );
192 assert_eq!(
193 internal_map.get(&Key::String(Arc::new("basename".to_string()))),
194 Some(&Value::String(".config".to_string().into()))
195 );
196 assert_eq!(
197 internal_map.get(&Key::String(Arc::new("parent".to_string()))),
198 Some(&Value::String("".to_string().into()))
199 );
200 assert_eq!(
201 internal_map.get(&Key::String(Arc::new("file_stem".to_string()))),
202 Some(&Value::String(".config".to_string().into()))
203 );
204 } else {
205 panic!("Expected a CEL Map Value");
206 }
207 }
208
209 #[test]
210 fn test_path_info_multiple_dots() {
211 let path_str = "archive.tar.gz";
212 let path_info = PathInfo::from(path_str);
213 let cel_value: Value = path_info.into();
214 if let Value::Map(map) = cel_value {
215 let internal_map = map.map.as_ref();
216 assert_eq!(
217 internal_map.get(&Key::String(Arc::new("ext".to_string()))),
218 Some(&Value::String("gz".to_string().into()))
219 );
220 assert_eq!(
221 internal_map.get(&Key::String(Arc::new("basename".to_string()))),
222 Some(&Value::String("archive.tar.gz".to_string().into()))
223 );
224 assert_eq!(
225 internal_map.get(&Key::String(Arc::new("parent".to_string()))),
226 Some(&Value::String("".to_string().into()))
227 );
228 assert_eq!(
229 internal_map.get(&Key::String(Arc::new("file_stem".to_string()))),
230 Some(&Value::String("archive.tar".to_string().into()))
231 );
232 } else {
233 panic!("Expected a CEL Map Value");
234 }
235 }
236
237 #[test]
238 fn test_path_info_trailing_slash() {
239 let path_str = "my/dir/";
240 let path_info = PathInfo::from(path_str);
241 let cel_value: Value = path_info.into();
242 if let Value::Map(map) = cel_value {
243 let internal_map = map.map.as_ref();
244 assert_eq!(
245 internal_map.get(&Key::String(Arc::new("ext".to_string()))),
246 Some(&Value::String("".to_string().into()))
247 );
248 assert_eq!(
249 internal_map.get(&Key::String(Arc::new("basename".to_string()))),
250 Some(&Value::String("dir".to_string().into()))
251 );
252 assert_eq!(
253 internal_map.get(&Key::String(Arc::new("parent".to_string()))),
254 Some(&Value::String("my".to_string().into()))
255 );
256 assert_eq!(
257 internal_map.get(&Key::String(Arc::new("file_stem".to_string()))),
258 Some(&Value::String("dir".to_string().into()))
259 );
260 } else {
261 panic!("Expected a CEL Map Value");
262 }
263 }
264
265 #[test]
266 fn test_path_info_empty_path() {
267 let path_str = "";
268 let path_info = PathInfo::from(path_str);
269 let cel_value: Value = path_info.into();
270 if let Value::Map(map) = cel_value {
271 let internal_map = map.map.as_ref();
272 assert_eq!(
273 internal_map.get(&Key::String(Arc::new("ext".to_string()))),
274 Some(&Value::String("".to_string().into()))
275 );
276 assert!(!internal_map.contains_key(&Key::String(Arc::new("basename".to_string()))));
277 assert!(!internal_map.contains_key(&Key::String(Arc::new("parent".to_string()))));
278 assert!(!internal_map.contains_key(&Key::String(Arc::new("file_stem".to_string()))));
279 } else {
280 panic!("Expected a CEL Map Value");
281 }
282 }
283}