fresh/view/file_tree/
search.rs1use crate::input::fuzzy::{fuzzy_match, FuzzyMatch};
8
9#[derive(Debug, Default, Clone)]
11pub struct FileExplorerSearch {
12 query: String,
14}
15
16impl FileExplorerSearch {
17 pub fn new() -> Self {
19 Self {
20 query: String::new(),
21 }
22 }
23
24 pub fn query(&self) -> &str {
26 &self.query
27 }
28
29 pub fn is_active(&self) -> bool {
31 !self.query.is_empty()
32 }
33
34 pub fn push_char(&mut self, c: char) {
36 self.query.push(c);
37 }
38
39 pub fn pop_char(&mut self) {
41 self.query.pop();
42 }
43
44 pub fn clear(&mut self) {
46 self.query.clear();
47 }
48
49 pub fn match_name(&self, name: &str) -> Option<FuzzyMatch> {
54 if self.query.is_empty() {
55 return None;
56 }
57 let result = fuzzy_match(&self.query, name);
58 if result.matched {
59 Some(result)
60 } else {
61 None
62 }
63 }
64
65 pub fn matches(&self, name: &str) -> bool {
67 if self.query.is_empty() {
68 true } else {
70 fuzzy_match(&self.query, name).matched
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_empty_search_matches_all() {
81 let search = FileExplorerSearch::new();
82 assert!(!search.is_active());
83 assert!(search.matches("anything"));
84 assert!(search.matches("file.txt"));
85 }
86
87 #[test]
88 fn test_search_query_operations() {
89 let mut search = FileExplorerSearch::new();
90
91 search.push_char('f');
92 assert_eq!(search.query(), "f");
93 assert!(search.is_active());
94
95 search.push_char('o');
96 search.push_char('o');
97 assert_eq!(search.query(), "foo");
98
99 search.pop_char();
100 assert_eq!(search.query(), "fo");
101
102 search.clear();
103 assert_eq!(search.query(), "");
104 assert!(!search.is_active());
105 }
106
107 #[test]
108 fn test_fuzzy_matching() {
109 let mut search = FileExplorerSearch::new();
110 search.push_char('m');
111 search.push_char('r');
112 search.push_char('s');
113
114 assert!(search.matches("main.rs"));
116
117 assert!(!search.matches("test.txt"));
119 }
120
121 #[test]
122 fn test_match_positions() {
123 let mut search = FileExplorerSearch::new();
124 search.push_char('m');
125 search.push_char('r');
126
127 let result = search.match_name("main.rs");
128 assert!(result.is_some());
129
130 let m = result.unwrap();
131 assert_eq!(m.match_positions.len(), 2);
132 assert_eq!(m.match_positions[0], 0); assert_eq!(m.match_positions[1], 5); }
135}