matrix_sdk_ui/room_list_service/filters/
normalized_match_room_name.rs1use tracing::error;
16
17use super::{normalize_string, Filter};
18
19struct NormalizedMatcher {
20 pattern: Option<String>,
21}
22
23impl NormalizedMatcher {
24 fn new() -> Self {
25 Self { pattern: None }
26 }
27
28 fn with_pattern(mut self, pattern: &str) -> Self {
29 self.pattern = Some(normalize_string(&pattern.to_lowercase()));
30
31 self
32 }
33
34 fn matches(&self, subject: &str) -> bool {
35 let Some(pattern) = self.pattern.as_ref() else { return true };
37
38 let subject = normalize_string(&subject.to_lowercase());
39
40 subject.contains(pattern)
41 }
42}
43
44pub fn new_filter(pattern: &str) -> impl Filter {
49 let searcher = NormalizedMatcher::new().with_pattern(pattern);
50
51 move |room| -> bool {
52 let Some(room_name) = room.cached_display_name() else {
53 error!(room_id = ?room.room_id(), "Missing cached room display name");
54
55 return false;
56 };
57
58 searcher.matches(&room_name.to_string())
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use std::ops::Not;
65
66 use super::*;
67
68 #[test]
69 fn test_no_pattern() {
70 let matcher = NormalizedMatcher::new();
71
72 assert!(matcher.matches("hello"));
73 }
74
75 #[test]
76 fn test_empty_pattern() {
77 let matcher = NormalizedMatcher::new();
78
79 assert!(matcher.matches("hello"));
80 }
81
82 #[test]
83 fn test_literal() {
84 let matcher = NormalizedMatcher::new();
85
86 let matcher = matcher.with_pattern("matrix");
87 assert!(matcher.matches("matrix"));
88
89 let matcher = matcher.with_pattern("matrxi");
90 assert!(matcher.matches("matrix").not());
91 }
92
93 #[test]
94 fn test_ignore_case() {
95 let matcher = NormalizedMatcher::new();
96
97 let matcher = matcher.with_pattern("matrix");
98 assert!(matcher.matches("MaTrIX"));
99
100 let matcher = matcher.with_pattern("matrxi");
101 assert!(matcher.matches("MaTrIX").not());
102 }
103
104 #[test]
105 fn test_normalization() {
106 let matcher = NormalizedMatcher::new();
107
108 let matcher = matcher.with_pattern("un été");
109
110 assert_eq!(matcher.pattern, Some("un ete".to_owned()));
112
113 assert!(matcher.matches("un été magnifique"));
115
116 let matcher = matcher.with_pattern("stefan");
118 assert!(matcher.matches("Ștefan"));
119 }
120}