athena_cli/utils/
filter.rs1pub fn matches_pattern<T: AsRef<str>>(value: T, pattern: &str) -> bool {
3 let value = value.as_ref();
4
5 if pattern.contains('*') {
7 let parts: Vec<&str> = pattern.split('*').collect();
8
9 if pattern.ends_with('*') && parts.len() == 2 {
11 return value.starts_with(parts[0]);
12 }
13
14 if pattern.starts_with('*') && parts.len() == 2 {
16 return value.ends_with(parts[1]);
17 }
18
19 if pattern.starts_with('*') && pattern.ends_with('*') && parts.len() == 3 {
21 return value.contains(parts[1]);
22 }
23 } else {
24 return value.to_lowercase().contains(&pattern.to_lowercase());
26 }
27
28 value == pattern
30}
31
32pub fn filter_items<'a, T, F>(items: &'a [T], pattern: Option<&str>, extractor: F) -> Vec<&'a T>
34where
35 F: Fn(&T) -> &str,
36{
37 match pattern {
38 Some(pattern) => items
39 .iter()
40 .filter(|item| matches_pattern(extractor(item), pattern))
41 .collect(),
42 None => items.iter().collect(),
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[derive(PartialEq, Debug)]
52 struct TestItem {
53 name: String,
54 category: String,
55 count: i32,
56 }
57
58 #[test]
59 fn test_matches_pattern() {
60 assert!(matches_pattern("hello", "hello"));
62
63 assert!(matches_pattern("hello world", "hello"));
65
66 assert!(matches_pattern("Hello World", "hello"));
68
69 assert!(matches_pattern("hello world", "hello*"));
71 assert!(matches_pattern("hello world", "*world"));
72 assert!(matches_pattern("hello world", "*lo wor*"));
73
74 assert!(!matches_pattern("hello", "world"));
76 assert!(!matches_pattern("hello", "hello world"));
77 }
78
79 #[test]
80 fn test_filter_items() {
81 let items = vec![
83 TestItem {
84 name: "Table1".to_string(),
85 category: "Data".to_string(),
86 count: 10,
87 },
88 TestItem {
89 name: "UserEvents".to_string(),
90 category: "Events".to_string(),
91 count: 20,
92 },
93 TestItem {
94 name: "EventLog".to_string(),
95 category: "Events".to_string(),
96 count: 30,
97 },
98 TestItem {
99 name: "Settings".to_string(),
100 category: "Config".to_string(),
101 count: 40,
102 },
103 ];
104
105 let filtered = filter_items(&items, Some("event"), |item| &item.name);
107 assert_eq!(filtered.len(), 2);
108 assert!(filtered.contains(&&items[1])); assert!(filtered.contains(&&items[2])); let filtered = filter_items(&items, Some("events"), |item| &item.category);
113 assert_eq!(filtered.len(), 2);
114 assert!(filtered.contains(&&items[1])); assert!(filtered.contains(&&items[2])); let filtered = filter_items(&items, Some("*Log"), |item| &item.name);
119 assert_eq!(filtered.len(), 1);
120 assert!(filtered.contains(&&items[2])); let filtered = filter_items(&items, Some("NonExistent"), |item| &item.name);
124 assert_eq!(filtered.len(), 0);
125
126 let filtered = filter_items(&items, None, |item| &item.name);
128 assert_eq!(filtered.len(), items.len());
129 }
130}