From 344a96a80f3d0efab2bc8fe87eeeca268ff324db Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 29 Jan 2024 14:23:05 +0100 Subject: [PATCH] feat: Introduce the `Filter` trait alias. This patch introduces the `matrix_sdk_ui::room_list_service::filters::Filter` trait alias. This patch also cleans up a little bit the filters by renaming some methods for the sake of consistency across all the existing filters. --- .../src/room_list_service/filters/all.rs | 4 ++- .../room_list_service/filters/all_non_left.rs | 14 ++++++-- .../filters/fuzzy_match_room_name.rs | 34 +++++++++---------- .../src/room_list_service/filters/mod.rs | 9 +++++ .../src/room_list_service/filters/none.rs | 4 +-- .../filters/normalized_match_room_name.rs | 26 +++++++------- 6 files changed, 55 insertions(+), 36 deletions(-) diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/all.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/all.rs index f12c613df..69b0f847c 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/all.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/all.rs @@ -1,7 +1,9 @@ use matrix_sdk::RoomListEntry; +use super::Filter; + /// Create a new filter that will accept all filled or invalidated entries. -pub fn new_filter() -> impl Fn(&RoomListEntry) -> bool { +pub fn new_filter() -> impl Filter { |room_list_entry| -> bool { matches!(room_list_entry, RoomListEntry::Filled(_) | RoomListEntry::Invalidated(_)) } diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/all_non_left.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/all_non_left.rs index 34d834884..01fe9bf25 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/all_non_left.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/all_non_left.rs @@ -1,11 +1,19 @@ use matrix_sdk::{Client, RoomListEntry}; use matrix_sdk_base::RoomState; -struct NonLeftRoomMatcher Option> { +use super::Filter; + +struct NonLeftRoomMatcher +where + F: Fn(&RoomListEntry) -> Option, +{ get_state: F, } -impl Option> NonLeftRoomMatcher { +impl NonLeftRoomMatcher +where + F: Fn(&RoomListEntry) -> Option, +{ fn matches(&self, room: &RoomListEntry) -> bool { if !matches!(room, RoomListEntry::Filled(_) | RoomListEntry::Invalidated(_)) { return false; @@ -21,7 +29,7 @@ impl Option> NonLeftRoomMatcher { /// Create a new filter that will accept all filled or invalidated entries, but /// filters out left rooms. -pub fn new_filter(client: &Client) -> impl Fn(&RoomListEntry) -> bool { +pub fn new_filter(client: &Client) -> impl Filter { let client = client.clone(); let matcher = NonLeftRoomMatcher { diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/fuzzy_match_room_name.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/fuzzy_match_room_name.rs index 1a0e2d634..9e8e672fd 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/fuzzy_match_room_name.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/fuzzy_match_room_name.rs @@ -1,7 +1,7 @@ pub use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher as _}; -use matrix_sdk::{Client, RoomListEntry}; +use matrix_sdk::Client; -use super::normalize_string; +use super::{normalize_string, Filter}; struct FuzzyMatcher { matcher: SkimMatcherV2, @@ -19,7 +19,7 @@ impl FuzzyMatcher { self } - fn fuzzy_match(&self, subject: &str) -> bool { + fn matches(&self, subject: &str) -> bool { // No pattern means there is a match. let Some(pattern) = self.pattern.as_ref() else { return true }; @@ -31,7 +31,7 @@ impl FuzzyMatcher { /// /// Rooms are fetched from the `Client`. The pattern and the room names are /// normalized with `normalize_string`. -pub fn new_filter(client: &Client, pattern: &str) -> impl Fn(&RoomListEntry) -> bool { +pub fn new_filter(client: &Client, pattern: &str) -> impl Filter { let searcher = FuzzyMatcher::new().with_pattern(pattern); let client = client.clone(); @@ -41,7 +41,7 @@ pub fn new_filter(client: &Client, pattern: &str) -> impl Fn(&RoomListEntry) -> let Some(room) = client.get_room(room_id) else { return false }; let Some(room_name) = room.name() else { return false }; - searcher.fuzzy_match(&room_name) + searcher.matches(&room_name) } } @@ -55,14 +55,14 @@ mod tests { fn test_no_pattern() { let matcher = FuzzyMatcher::new(); - assert!(matcher.fuzzy_match("hello")); + assert!(matcher.matches("hello")); } #[test] fn test_empty_pattern() { let matcher = FuzzyMatcher::new(); - assert!(matcher.fuzzy_match("hello")); + assert!(matcher.matches("hello")); } #[test] @@ -70,10 +70,10 @@ mod tests { let matcher = FuzzyMatcher::new(); let matcher = matcher.with_pattern("mtx"); - assert!(matcher.fuzzy_match("matrix")); + assert!(matcher.matches("matrix")); let matcher = matcher.with_pattern("mxt"); - assert!(matcher.fuzzy_match("matrix").not()); + assert!(matcher.matches("matrix").not()); } #[test] @@ -81,10 +81,10 @@ mod tests { let matcher = FuzzyMatcher::new(); let matcher = matcher.with_pattern("mtx"); - assert!(matcher.fuzzy_match("MaTrIX")); + assert!(matcher.matches("MaTrIX")); let matcher = matcher.with_pattern("mxt"); - assert!(matcher.fuzzy_match("MaTrIX").not()); + assert!(matcher.matches("MaTrIX").not()); } #[test] @@ -92,12 +92,12 @@ mod tests { let matcher = FuzzyMatcher::new(); let matcher = matcher.with_pattern("mtx"); - assert!(matcher.fuzzy_match("matrix")); - assert!(matcher.fuzzy_match("Matrix")); + assert!(matcher.matches("matrix")); + assert!(matcher.matches("Matrix")); let matcher = matcher.with_pattern("Mtx"); - assert!(matcher.fuzzy_match("matrix").not()); - assert!(matcher.fuzzy_match("Matrix")); + assert!(matcher.matches("matrix").not()); + assert!(matcher.matches("Matrix")); } #[test] @@ -110,10 +110,10 @@ mod tests { assert_eq!(matcher.pattern, Some("ubete".to_owned())); // Second, assert that the subject is normalized too. - assert!(matcher.fuzzy_match("un bel été")); + assert!(matcher.matches("un bel été")); // Another concrete test. let matcher = matcher.with_pattern("stf"); - assert!(matcher.fuzzy_match("Ștefan")); + assert!(matcher.matches("Ștefan")); } } diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs index b1beefa85..99e85c231 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs @@ -7,10 +7,19 @@ mod normalized_match_room_name; pub use all::new_filter as new_filter_all; pub use all_non_left::new_filter as new_filter_all_non_left; pub use fuzzy_match_room_name::new_filter as new_filter_fuzzy_match_room_name; +use matrix_sdk::RoomListEntry; pub use none::new_filter as new_filter_none; pub use normalized_match_room_name::new_filter as new_filter_normalized_match_room_name; use unicode_normalization::{char::is_combining_mark, UnicodeNormalization}; +/// A trait “alias” that represents a _filter_. +/// +/// A filter is simply a function that receives a `&RoomListEntry` and returns a +/// `bool`. +pub trait Filter: Fn(&RoomListEntry) -> bool {} + +impl Filter for F where F: Fn(&RoomListEntry) -> bool {} + /// Normalize a string, i.e. decompose it into NFD (Normalization Form D, i.e. a /// canonical decomposition, see http://www.unicode.org/reports/tr15/) and /// filter out the combining marks. diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/none.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/none.rs index a500fe7de..99e97be9c 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/none.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/none.rs @@ -1,7 +1,7 @@ -use matrix_sdk::RoomListEntry; +use super::Filter; /// Create a new filter that will reject all entries. -pub fn new_filter() -> impl Fn(&RoomListEntry) -> bool { +pub fn new_filter() -> impl Filter { |_room_list_entry| -> bool { false } } diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/normalized_match_room_name.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/normalized_match_room_name.rs index 7ee8fab5b..c0a49602d 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/normalized_match_room_name.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/normalized_match_room_name.rs @@ -1,6 +1,6 @@ -use matrix_sdk::{Client, RoomListEntry}; +use matrix_sdk::Client; -use super::normalize_string; +use super::{normalize_string, Filter}; struct NormalizedMatcher { pattern: Option, @@ -17,7 +17,7 @@ impl NormalizedMatcher { self } - fn normalized_match(&self, subject: &str) -> bool { + fn matches(&self, subject: &str) -> bool { // No pattern means there is a match. let Some(pattern) = self.pattern.as_ref() else { return true }; @@ -31,7 +31,7 @@ impl NormalizedMatcher { /// /// Rooms are fetched from the `Client`. The pattern and the room names are /// normalized with `normalize_string`. -pub fn new_filter(client: &Client, pattern: &str) -> impl Fn(&RoomListEntry) -> bool { +pub fn new_filter(client: &Client, pattern: &str) -> impl Filter { let searcher = NormalizedMatcher::new().with_pattern(pattern); let client = client.clone(); @@ -41,7 +41,7 @@ pub fn new_filter(client: &Client, pattern: &str) -> impl Fn(&RoomListEntry) -> let Some(room) = client.get_room(room_id) else { return false }; let Some(room_name) = room.name() else { return false }; - searcher.normalized_match(&room_name) + searcher.matches(&room_name) } } @@ -55,14 +55,14 @@ mod tests { fn test_no_pattern() { let matcher = NormalizedMatcher::new(); - assert!(matcher.normalized_match("hello")); + assert!(matcher.matches("hello")); } #[test] fn test_empty_pattern() { let matcher = NormalizedMatcher::new(); - assert!(matcher.normalized_match("hello")); + assert!(matcher.matches("hello")); } #[test] @@ -70,10 +70,10 @@ mod tests { let matcher = NormalizedMatcher::new(); let matcher = matcher.with_pattern("matrix"); - assert!(matcher.normalized_match("matrix")); + assert!(matcher.matches("matrix")); let matcher = matcher.with_pattern("matrxi"); - assert!(matcher.normalized_match("matrix").not()); + assert!(matcher.matches("matrix").not()); } #[test] @@ -81,10 +81,10 @@ mod tests { let matcher = NormalizedMatcher::new(); let matcher = matcher.with_pattern("matrix"); - assert!(matcher.normalized_match("MaTrIX")); + assert!(matcher.matches("MaTrIX")); let matcher = matcher.with_pattern("matrxi"); - assert!(matcher.normalized_match("MaTrIX").not()); + assert!(matcher.matches("MaTrIX").not()); } #[test] @@ -97,10 +97,10 @@ mod tests { assert_eq!(matcher.pattern, Some("un ete".to_owned())); // Second, assert that the subject is normalized too. - assert!(matcher.normalized_match("un été magnifique")); + assert!(matcher.matches("un été magnifique")); // Another concrete test. let matcher = matcher.with_pattern("stefan"); - assert!(matcher.normalized_match("Ștefan")); + assert!(matcher.matches("Ștefan")); } }