nodedb_query/scan_filter/
like.rs1pub fn sql_like_match(input: &str, pattern: &str, case_insensitive: bool) -> bool {
8 let (input, pattern) = if case_insensitive {
9 (input.to_lowercase(), pattern.to_lowercase())
10 } else {
11 (input.to_string(), pattern.to_string())
12 };
13
14 let input = input.as_bytes();
15 let pattern = pattern.as_bytes();
16
17 let (mut i, mut j) = (0usize, 0usize);
18 let (mut star_j, mut star_i) = (usize::MAX, 0usize);
19
20 while i < input.len() {
21 if j < pattern.len() && (pattern[j] == b'_' || pattern[j] == input[i]) {
22 i += 1;
23 j += 1;
24 } else if j < pattern.len() && pattern[j] == b'%' {
25 star_j = j;
26 star_i = i;
27 j += 1;
28 } else if star_j != usize::MAX {
29 star_i += 1;
30 i = star_i;
31 j = star_j + 1;
32 } else {
33 return false;
34 }
35 }
36
37 while j < pattern.len() && pattern[j] == b'%' {
38 j += 1;
39 }
40
41 j == pattern.len()
42}
43
44#[cfg(test)]
45mod tests {
46 use super::sql_like_match;
47
48 #[test]
49 fn like_basic() {
50 assert!(sql_like_match("hello world", "%world", false));
51 assert!(sql_like_match("hello world", "hello%", false));
52 assert!(!sql_like_match("hello world", "xyz%", false));
53 }
54
55 #[test]
56 fn ilike_case_insensitive() {
57 assert!(sql_like_match("Hello", "hello", true));
58 assert!(sql_like_match("WORLD", "%world%", true));
59 }
60}