1use super::Field;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
5#[serde(rename_all = "snake_case")]
6pub enum FilterOperator {
7 Eq,
8 Neq,
9 Gt,
10 Gte,
11 Lt,
12 Lte,
13 Like,
14 Ilike,
15 Match,
16 Imatch,
17 In,
18 Is,
19 Fts,
20 Plfts,
21 Phfts,
22 Wfts,
23 Cs,
24 Cd,
25 Ov,
26 Sl,
27 Sr,
28 Nxl,
29 Nxr,
30 Adj,
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
34#[serde(rename_all = "snake_case")]
35pub enum Quantifier {
36 Any,
37 All,
38}
39
40#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
41#[serde(untagged)]
42pub enum FilterValue {
43 Single(String),
44 List(Vec<String>),
45}
46
47impl FilterValue {
48 pub fn as_str(&self) -> Option<&str> {
49 match self {
50 FilterValue::Single(s) => Some(s.as_str()),
51 FilterValue::List(_) => None,
52 }
53 }
54
55 pub fn as_list(&self) -> Option<&[String]> {
56 match self {
57 FilterValue::Single(_) => None,
58 FilterValue::List(list) => Some(list.as_slice()),
59 }
60 }
61
62 pub fn to_json(&self) -> serde_json::Value {
63 match self {
64 FilterValue::Single(s) => serde_json::Value::String(s.clone()),
65 FilterValue::List(list) => serde_json::Value::Array(
66 list.iter()
67 .map(|s| {
68 if let Ok(i) = s.parse::<i64>() {
69 serde_json::Value::Number(i.into())
70 } else if let Ok(f) = s.parse::<f64>() {
71 if let Some(num) = serde_json::Number::from_f64(f) {
72 serde_json::Value::Number(num)
73 } else {
74 serde_json::Value::String(s.clone())
75 }
76 } else {
77 serde_json::Value::String(s.clone())
78 }
79 })
80 .collect(),
81 ),
82 }
83 }
84}
85
86impl From<&str> for FilterValue {
87 fn from(s: &str) -> Self {
88 FilterValue::Single(s.to_string())
89 }
90}
91
92impl From<String> for FilterValue {
93 fn from(s: String) -> Self {
94 FilterValue::Single(s)
95 }
96}
97
98impl From<Vec<String>> for FilterValue {
99 fn from(v: Vec<String>) -> Self {
100 FilterValue::List(v)
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
105pub struct Filter {
106 pub field: Field,
107 pub operator: FilterOperator,
108 pub value: FilterValue,
109 pub quantifier: Option<Quantifier>,
110 pub language: Option<String>,
111 pub negated: bool,
112}
113
114impl Filter {
115 pub fn new(field: Field, operator: FilterOperator, value: FilterValue) -> Self {
116 Self {
117 field,
118 operator,
119 value,
120 quantifier: None,
121 language: None,
122 negated: false,
123 }
124 }
125
126 pub fn with_quantifier(mut self, quantifier: Quantifier) -> Self {
127 self.quantifier = Some(quantifier);
128 self
129 }
130
131 pub fn with_language(mut self, language: impl Into<String>) -> Self {
132 self.language = Some(language.into());
133 self
134 }
135
136 pub fn negated(mut self) -> Self {
137 self.negated = true;
138 self
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145
146 #[test]
147 fn test_filter_new() {
148 let field = Field::new("id");
149 let filter = Filter::new(
150 field,
151 FilterOperator::Eq,
152 FilterValue::Single("1".to_string()),
153 );
154
155 assert_eq!(filter.operator, FilterOperator::Eq);
156 assert!(!filter.negated);
157 assert!(filter.quantifier.is_none());
158 }
159
160 #[test]
161 fn test_filter_with_quantifier() {
162 let field = Field::new("status");
163 let filter = Filter::new(
164 field,
165 FilterOperator::Eq,
166 FilterValue::List(vec!["active".to_string(), "pending".to_string()]),
167 )
168 .with_quantifier(Quantifier::Any);
169
170 assert_eq!(filter.quantifier, Some(Quantifier::Any));
171 }
172
173 #[test]
174 fn test_filter_negated() {
175 let field = Field::new("status");
176 let filter = Filter::new(
177 field,
178 FilterOperator::Eq,
179 FilterValue::Single("deleted".to_string()),
180 )
181 .negated();
182
183 assert!(filter.negated);
184 }
185
186 #[test]
187 fn test_filter_value_as_str() {
188 let value = FilterValue::Single("test".to_string());
189 assert_eq!(value.as_str(), Some("test"));
190 }
191
192 #[test]
193 fn test_filter_value_as_list() {
194 let value = FilterValue::List(vec!["a".to_string(), "b".to_string()]);
195 let expected: Vec<String> = vec!["a".to_string(), "b".to_string()];
196 assert_eq!(value.as_list(), Some(expected.as_slice()));
197 }
198
199 #[test]
200 fn test_filter_value_to_json() {
201 let value = FilterValue::Single("test".to_string());
202 let json = value.to_json();
203 assert_eq!(json, serde_json::Value::String("test".to_string()));
204 }
205
206 #[test]
207 fn test_filter_value_list_to_json() {
208 let value = FilterValue::List(vec!["1".to_string(), "2".to_string(), "3".to_string()]);
209 let json = value.to_json();
210 match json {
211 serde_json::Value::Array(arr) => {
212 assert_eq!(arr.len(), 3);
213 assert_eq!(arr[0], serde_json::Value::Number(1.into()));
214 }
215 _ => panic!("Expected array"),
216 }
217 }
218}