1use std::marker::PhantomData;
11
12use serde_json::{Map, Value};
13
14use super::{
15 Common, FlussoValue, RangeRelation, Sort, SortOrder, common_opts, exists_q, kind, single, wrap,
16};
17use crate::query::{AsQuery, Query, Root};
18
19fn date_value(value: &(impl FlussoValue<kind::Date> + serde::Serialize)) -> Value {
24 match serde_json::to_value(value) {
25 Ok(Value::String(string)) => Value::String(string),
26 Ok(other) => Value::String(other.to_string()),
27 Err(_) => Value::String(String::new()),
28 }
29}
30
31#[derive(Debug, Clone)]
34pub struct EqQuery<S = Root> {
35 path: String,
36 value: Value,
37 common: Common,
38 _scope: PhantomData<fn() -> S>,
39}
40
41impl<S> EqQuery<S> {
42 fn new(path: &str, value: Value) -> Self {
43 Self {
44 path: path.to_string(),
45 value,
46 common: Common::default(),
47 _scope: PhantomData,
48 }
49 }
50
51 common_opts!(common);
52}
53
54impl<S> AsQuery<S> for EqQuery<S> {
55 fn into_query(self) -> Option<Query<S>> {
56 if self.common.is_empty() {
57 Some(single("term", &self.path, self.value))
58 } else {
59 let mut body = Map::new();
60 body.insert("value".to_string(), self.value);
61 self.common.write(&mut body);
62 Some(single("term", &self.path, Value::Object(body)))
63 }
64 }
65}
66
67#[derive(Debug, Clone)]
70pub struct TermsQuery<S = Root> {
71 path: String,
72 values: Vec<Value>,
73 common: Common,
74 _scope: PhantomData<fn() -> S>,
75}
76
77impl<S> TermsQuery<S> {
78 pub(crate) fn new(path: &str, values: Vec<Value>) -> Self {
79 Self {
80 path: path.to_string(),
81 values,
82 common: Common::default(),
83 _scope: PhantomData,
84 }
85 }
86
87 common_opts!(common);
88}
89
90impl<S> AsQuery<S> for TermsQuery<S> {
91 fn into_query(self) -> Option<Query<S>> {
92 let mut body = Map::new();
94 body.insert(self.path, Value::Array(self.values));
95 self.common.write(&mut body);
96 Some(wrap("terms", body))
97 }
98}
99
100#[derive(Debug, Clone)]
103pub struct RangeQuery<S = Root> {
104 path: String,
105 bounds: Vec<(&'static str, Value)>,
106 extra: Map<String, Value>,
107 common: Common,
108 _scope: PhantomData<fn() -> S>,
109}
110
111impl<S> RangeQuery<S> {
112 pub(crate) fn new(path: &str, bounds: Vec<(&'static str, Value)>) -> Self {
113 Self {
114 path: path.to_string(),
115 bounds,
116 extra: Map::new(),
117 common: Common::default(),
118 _scope: PhantomData,
119 }
120 }
121
122 #[must_use]
124 pub fn format(mut self, format: impl Into<String>) -> Self {
125 self.extra
126 .insert("format".to_string(), Value::String(format.into()));
127 self
128 }
129
130 #[must_use]
132 pub fn time_zone(mut self, time_zone: impl Into<String>) -> Self {
133 self.extra
134 .insert("time_zone".to_string(), Value::String(time_zone.into()));
135 self
136 }
137
138 #[must_use]
141 pub fn relation(mut self, relation: RangeRelation) -> Self {
142 self.extra.insert(
143 "relation".to_string(),
144 Value::String(relation.as_str().to_string()),
145 );
146 self
147 }
148
149 common_opts!(common);
150}
151
152impl<S> AsQuery<S> for RangeQuery<S> {
153 fn into_query(self) -> Option<Query<S>> {
154 let mut body = self.extra;
155 for (key, value) in self.bounds {
156 body.insert(key.to_string(), value);
157 }
158 self.common.write(&mut body);
159 Some(single("range", &self.path, Value::Object(body)))
160 }
161}
162
163#[derive(Debug, Clone)]
165pub struct Bool<S = Root> {
166 path: String,
167 _scope: PhantomData<fn() -> S>,
168}
169
170impl<S> Bool<S> {
171 pub fn at(path: impl Into<String>) -> Self {
172 Self {
173 path: path.into(),
174 _scope: PhantomData,
175 }
176 }
177
178 pub fn eq(&self, value: bool) -> EqQuery<S> {
180 EqQuery::new(&self.path, Value::Bool(value))
181 }
182
183 pub fn exists(&self) -> Query<S> {
185 exists_q(&self.path)
186 }
187
188 pub fn asc(&self) -> Sort {
189 Sort::new(&self.path, SortOrder::Asc)
190 }
191
192 pub fn desc(&self) -> Sort {
193 Sort::new(&self.path, SortOrder::Desc)
194 }
195}
196
197#[derive(Debug, Clone)]
200pub struct Number<T, S = Root> {
201 path: String,
202 _marker: PhantomData<fn() -> (T, S)>,
203}
204
205impl<T, S> Number<T, S>
206where
207 T: Into<Value> + Copy,
208{
209 pub fn at(path: impl Into<String>) -> Self {
210 Self {
211 path: path.into(),
212 _marker: PhantomData,
213 }
214 }
215
216 pub fn eq(&self, value: T) -> EqQuery<S> {
218 EqQuery::new(&self.path, value.into())
219 }
220
221 pub fn any_of(&self, values: impl IntoIterator<Item = T>) -> TermsQuery<S> {
223 let array = values.into_iter().map(Into::into).collect();
224 TermsQuery::new(&self.path, array)
225 }
226
227 pub fn lt(&self, value: T) -> RangeQuery<S> {
229 RangeQuery::new(&self.path, vec![("lt", value.into())])
230 }
231
232 pub fn lte(&self, value: T) -> RangeQuery<S> {
234 RangeQuery::new(&self.path, vec![("lte", value.into())])
235 }
236
237 pub fn gt(&self, value: T) -> RangeQuery<S> {
239 RangeQuery::new(&self.path, vec![("gt", value.into())])
240 }
241
242 pub fn gte(&self, value: T) -> RangeQuery<S> {
244 RangeQuery::new(&self.path, vec![("gte", value.into())])
245 }
246
247 pub fn between(&self, low: T, high: T) -> RangeQuery<S> {
249 RangeQuery::new(&self.path, vec![("gte", low.into()), ("lte", high.into())])
250 }
251
252 pub fn exists(&self) -> Query<S> {
254 exists_q(&self.path)
255 }
256
257 pub fn asc(&self) -> Sort {
258 Sort::new(&self.path, SortOrder::Asc)
259 }
260
261 pub fn desc(&self) -> Sort {
262 Sort::new(&self.path, SortOrder::Desc)
263 }
264}
265
266#[derive(Debug, Clone)]
268pub struct Date<S = Root> {
269 path: String,
270 _scope: PhantomData<fn() -> S>,
271}
272
273impl<S> Date<S> {
274 pub fn at(path: impl Into<String>) -> Self {
275 Self {
276 path: path.into(),
277 _scope: PhantomData,
278 }
279 }
280
281 pub fn eq(&self, value: impl FlussoValue<kind::Date> + serde::Serialize) -> EqQuery<S> {
284 EqQuery::new(&self.path, date_value(&value))
285 }
286
287 pub fn any_of(
289 &self,
290 values: impl IntoIterator<Item = impl FlussoValue<kind::Date> + serde::Serialize>,
291 ) -> TermsQuery<S> {
292 let array = values.into_iter().map(|v| date_value(&v)).collect();
293 TermsQuery::new(&self.path, array)
294 }
295
296 pub fn lt(&self, value: impl FlussoValue<kind::Date> + serde::Serialize) -> RangeQuery<S> {
298 RangeQuery::new(&self.path, vec![("lt", date_value(&value))])
299 }
300
301 pub fn lte(&self, value: impl FlussoValue<kind::Date> + serde::Serialize) -> RangeQuery<S> {
303 RangeQuery::new(&self.path, vec![("lte", date_value(&value))])
304 }
305
306 pub fn gt(&self, value: impl FlussoValue<kind::Date> + serde::Serialize) -> RangeQuery<S> {
308 RangeQuery::new(&self.path, vec![("gt", date_value(&value))])
309 }
310
311 pub fn gte(&self, value: impl FlussoValue<kind::Date> + serde::Serialize) -> RangeQuery<S> {
313 RangeQuery::new(&self.path, vec![("gte", date_value(&value))])
314 }
315
316 pub fn between(
318 &self,
319 low: impl FlussoValue<kind::Date> + serde::Serialize,
320 high: impl FlussoValue<kind::Date> + serde::Serialize,
321 ) -> RangeQuery<S> {
322 RangeQuery::new(
323 &self.path,
324 vec![("gte", date_value(&low)), ("lte", date_value(&high))],
325 )
326 }
327
328 pub fn exists(&self) -> Query<S> {
330 exists_q(&self.path)
331 }
332
333 pub fn asc(&self) -> Sort {
334 Sort::new(&self.path, SortOrder::Asc)
335 }
336
337 pub fn desc(&self) -> Sort {
338 Sort::new(&self.path, SortOrder::Desc)
339 }
340}