1use std::marker::PhantomData;
11
12use serde_json::{Map, Value};
13
14use super::{Common, Sort, SortOrder, common_opts, exists_q, single, wrap};
15use crate::query::{AsQuery, Query, Root};
16
17#[derive(Debug, Clone)]
20pub struct EqQuery<S = Root> {
21 path: String,
22 value: Value,
23 common: Common,
24 _scope: PhantomData<fn() -> S>,
25}
26
27impl<S> EqQuery<S> {
28 fn new(path: &str, value: Value) -> Self {
29 Self {
30 path: path.to_string(),
31 value,
32 common: Common::default(),
33 _scope: PhantomData,
34 }
35 }
36
37 common_opts!(common);
38}
39
40impl<S> AsQuery<S> for EqQuery<S> {
41 fn into_query(self) -> Option<Query<S>> {
42 if self.common.is_empty() {
43 Some(single("term", &self.path, self.value))
44 } else {
45 let mut body = Map::new();
46 body.insert("value".to_string(), self.value);
47 self.common.write(&mut body);
48 Some(single("term", &self.path, Value::Object(body)))
49 }
50 }
51}
52
53#[derive(Debug, Clone)]
56pub struct TermsQuery<S = Root> {
57 path: String,
58 values: Vec<Value>,
59 common: Common,
60 _scope: PhantomData<fn() -> S>,
61}
62
63impl<S> TermsQuery<S> {
64 pub(crate) fn new(path: &str, values: Vec<Value>) -> Self {
65 Self {
66 path: path.to_string(),
67 values,
68 common: Common::default(),
69 _scope: PhantomData,
70 }
71 }
72
73 common_opts!(common);
74}
75
76impl<S> AsQuery<S> for TermsQuery<S> {
77 fn into_query(self) -> Option<Query<S>> {
78 let mut body = Map::new();
80 body.insert(self.path, Value::Array(self.values));
81 self.common.write(&mut body);
82 Some(wrap("terms", body))
83 }
84}
85
86#[derive(Debug, Clone)]
89pub struct RangeQuery<S = Root> {
90 path: String,
91 bounds: Vec<(&'static str, Value)>,
92 extra: Map<String, Value>,
93 common: Common,
94 _scope: PhantomData<fn() -> S>,
95}
96
97impl<S> RangeQuery<S> {
98 pub(crate) fn new(path: &str, bounds: Vec<(&'static str, Value)>) -> Self {
99 Self {
100 path: path.to_string(),
101 bounds,
102 extra: Map::new(),
103 common: Common::default(),
104 _scope: PhantomData,
105 }
106 }
107
108 #[must_use]
110 pub fn format(mut self, format: impl Into<String>) -> Self {
111 self.extra
112 .insert("format".to_string(), Value::String(format.into()));
113 self
114 }
115
116 #[must_use]
118 pub fn time_zone(mut self, time_zone: impl Into<String>) -> Self {
119 self.extra
120 .insert("time_zone".to_string(), Value::String(time_zone.into()));
121 self
122 }
123
124 #[must_use]
127 pub fn relation(mut self, relation: impl Into<String>) -> Self {
128 self.extra
129 .insert("relation".to_string(), Value::String(relation.into()));
130 self
131 }
132
133 common_opts!(common);
134}
135
136impl<S> AsQuery<S> for RangeQuery<S> {
137 fn into_query(self) -> Option<Query<S>> {
138 let mut body = self.extra;
139 for (key, value) in self.bounds {
140 body.insert(key.to_string(), value);
141 }
142 self.common.write(&mut body);
143 Some(single("range", &self.path, Value::Object(body)))
144 }
145}
146
147#[derive(Debug, Clone)]
149pub struct Bool<S = Root> {
150 path: String,
151 _scope: PhantomData<fn() -> S>,
152}
153
154impl<S> Bool<S> {
155 pub fn at(path: impl Into<String>) -> Self {
156 Self {
157 path: path.into(),
158 _scope: PhantomData,
159 }
160 }
161
162 pub fn eq(&self, value: bool) -> EqQuery<S> {
164 EqQuery::new(&self.path, Value::Bool(value))
165 }
166
167 pub fn exists(&self) -> Query<S> {
169 exists_q(&self.path)
170 }
171}
172
173#[derive(Debug, Clone)]
176pub struct Number<T, S = Root> {
177 path: String,
178 _marker: PhantomData<fn() -> (T, S)>,
179}
180
181impl<T, S> Number<T, S>
182where
183 T: Into<Value> + Copy,
184{
185 pub fn at(path: impl Into<String>) -> Self {
186 Self {
187 path: path.into(),
188 _marker: PhantomData,
189 }
190 }
191
192 pub fn eq(&self, value: T) -> EqQuery<S> {
194 EqQuery::new(&self.path, value.into())
195 }
196
197 pub fn in_(&self, values: impl IntoIterator<Item = T>) -> TermsQuery<S> {
199 let array = values.into_iter().map(Into::into).collect();
200 TermsQuery::new(&self.path, array)
201 }
202
203 pub fn lt(&self, value: T) -> RangeQuery<S> {
205 RangeQuery::new(&self.path, vec![("lt", value.into())])
206 }
207
208 pub fn lte(&self, value: T) -> RangeQuery<S> {
210 RangeQuery::new(&self.path, vec![("lte", value.into())])
211 }
212
213 pub fn gt(&self, value: T) -> RangeQuery<S> {
215 RangeQuery::new(&self.path, vec![("gt", value.into())])
216 }
217
218 pub fn gte(&self, value: T) -> RangeQuery<S> {
220 RangeQuery::new(&self.path, vec![("gte", value.into())])
221 }
222
223 pub fn between(&self, low: T, high: T) -> RangeQuery<S> {
225 RangeQuery::new(&self.path, vec![("gte", low.into()), ("lte", high.into())])
226 }
227
228 pub fn exists(&self) -> Query<S> {
230 exists_q(&self.path)
231 }
232
233 pub fn asc(&self) -> Sort {
234 Sort::new(&self.path, SortOrder::Asc)
235 }
236
237 pub fn desc(&self) -> Sort {
238 Sort::new(&self.path, SortOrder::Desc)
239 }
240}
241
242#[derive(Debug, Clone)]
244pub struct Date<S = Root> {
245 path: String,
246 _scope: PhantomData<fn() -> S>,
247}
248
249impl<S> Date<S> {
250 pub fn at(path: impl Into<String>) -> Self {
251 Self {
252 path: path.into(),
253 _scope: PhantomData,
254 }
255 }
256
257 pub fn eq(&self, value: impl Into<String>) -> EqQuery<S> {
259 EqQuery::new(&self.path, Value::String(value.into()))
260 }
261
262 pub fn lt(&self, value: impl Into<String>) -> RangeQuery<S> {
264 RangeQuery::new(&self.path, vec![("lt", Value::String(value.into()))])
265 }
266
267 pub fn lte(&self, value: impl Into<String>) -> RangeQuery<S> {
269 RangeQuery::new(&self.path, vec![("lte", Value::String(value.into()))])
270 }
271
272 pub fn gt(&self, value: impl Into<String>) -> RangeQuery<S> {
274 RangeQuery::new(&self.path, vec![("gt", Value::String(value.into()))])
275 }
276
277 pub fn gte(&self, value: impl Into<String>) -> RangeQuery<S> {
279 RangeQuery::new(&self.path, vec![("gte", Value::String(value.into()))])
280 }
281
282 pub fn between(&self, low: impl Into<String>, high: impl Into<String>) -> RangeQuery<S> {
284 RangeQuery::new(
285 &self.path,
286 vec![
287 ("gte", Value::String(low.into())),
288 ("lte", Value::String(high.into())),
289 ],
290 )
291 }
292
293 pub fn exists(&self) -> Query<S> {
295 exists_q(&self.path)
296 }
297
298 pub fn asc(&self) -> Sort {
299 Sort::new(&self.path, SortOrder::Asc)
300 }
301
302 pub fn desc(&self) -> Sort {
303 Sort::new(&self.path, SortOrder::Desc)
304 }
305}