paginator_utils/
search.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
4pub struct SearchParams {
5    pub query: String,
6    pub fields: Vec<String>,
7    #[serde(default)]
8    pub case_sensitive: bool,
9    #[serde(default)]
10    pub exact_match: bool,
11}
12
13impl SearchParams {
14    pub fn new(query: impl Into<String>, fields: Vec<String>) -> Self {
15        Self {
16            query: query.into(),
17            fields,
18            case_sensitive: false,
19            exact_match: false,
20        }
21    }
22
23    pub fn with_case_sensitive(mut self, sensitive: bool) -> Self {
24        self.case_sensitive = sensitive;
25        self
26    }
27
28    pub fn with_exact_match(mut self, exact: bool) -> Self {
29        self.exact_match = exact;
30        self
31    }
32
33    pub fn to_sql_where(&self) -> String {
34        let pattern = if self.exact_match {
35            format!("'{}'", self.query.replace('\'', "''"))
36        } else {
37            format!("'%{}%'", self.query.replace('\'', "''"))
38        };
39
40        let operator = if self.case_sensitive { "LIKE" } else { "ILIKE" };
41
42        let conditions: Vec<String> = self
43            .fields
44            .iter()
45            .map(|field| {
46                if self.case_sensitive || operator == "ILIKE" {
47                    format!("{} {} {}", field, operator, pattern)
48                } else {
49                    format!("LOWER({}) LIKE LOWER({})", field, pattern)
50                }
51            })
52            .collect();
53
54        format!("({})", conditions.join(" OR "))
55    }
56}