elasticsearch_dsl/search/params/
term.rs

1use serde::ser::{self, Serialize};
2
3/// Elasticsearch term value
4#[derive(Clone, Serialize)]
5#[serde(untagged)]
6pub enum Term {
7    /// Boolean value
8    Boolean(bool),
9
10    /// Positive only integer number
11    PositiveNumber(u64),
12
13    /// Negative only integer number
14    NegativeNumber(i64),
15
16    /// 32-bit floating point number, separate from 64-bit to not lose precision
17    Float32(f32),
18
19    /// 64-bit floating point number, separate from 32-bit to not lose precision
20    Float64(f64),
21
22    /// A string value
23    String(String),
24}
25
26impl std::fmt::Debug for Term {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        match self {
29            Self::Boolean(term) => term.fmt(f),
30            Self::PositiveNumber(term) => term.fmt(f),
31            Self::NegativeNumber(term) => term.fmt(f),
32            Self::Float32(term) => term.fmt(f),
33            Self::Float64(term) => term.fmt(f),
34            Self::String(term) => term.fmt(f),
35        }
36    }
37}
38
39impl PartialEq for Term {
40    fn eq(&self, other: &Self) -> bool {
41        match (self, other) {
42            (Self::Boolean(l0), Self::Boolean(r0)) => l0 == r0,
43            (Self::PositiveNumber(l0), Self::PositiveNumber(r0)) => l0 == r0,
44            (Self::NegativeNumber(l0), Self::NegativeNumber(r0)) => l0 == r0,
45            (Self::Float32(l0), Self::Float32(r0)) => l0 == r0,
46            (Self::Float64(l0), Self::Float64(r0)) => l0 == r0,
47            (Self::Float32(l0), Self::Float64(r0)) => l0 == &(*r0 as f32),
48            (Self::Float64(l0), Self::Float32(r0)) => &(*l0 as f32) == r0,
49            (Self::String(l0), Self::String(r0)) => l0 == r0,
50            _ => false,
51        }
52    }
53}
54
55impl Term {
56    /// Creates a new term from a serializable value
57    pub fn new<T>(term: T) -> Option<Self>
58    where
59        T: Serialize,
60    {
61        let term = term.serialize(Serializer);
62
63        debug_assert!(term.is_ok() || term == Err(TermSerializeError::NoTerm));
64
65        term.ok()
66    }
67}
68
69struct Serializer;
70
71impl ser::Serializer for Serializer {
72    type Ok = Term;
73    type Error = TermSerializeError;
74    type SerializeSeq = Self;
75    type SerializeTuple = Self;
76    type SerializeTupleStruct = Self;
77    type SerializeTupleVariant = Self;
78    type SerializeMap = Self;
79    type SerializeStruct = Self;
80    type SerializeStructVariant = Self;
81
82    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
83        Ok(Term::Boolean(v))
84    }
85
86    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
87        self.serialize_i64(v as i64)
88    }
89
90    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
91        self.serialize_i64(v as i64)
92    }
93
94    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
95        self.serialize_i64(v as i64)
96    }
97
98    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
99        if v < 0 {
100            Ok(Term::NegativeNumber(v))
101        } else {
102            Ok(Term::PositiveNumber(v as u64))
103        }
104    }
105
106    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
107        self.serialize_u64(v as u64)
108    }
109
110    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
111        self.serialize_u64(v as u64)
112    }
113
114    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
115        self.serialize_u64(v as u64)
116    }
117
118    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
119        Ok(Term::PositiveNumber(v))
120    }
121
122    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
123        Ok(Term::Float32(v))
124    }
125
126    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
127        Ok(Term::Float64(v))
128    }
129
130    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
131        let v = String::from(v);
132
133        if v.is_empty() {
134            Err(TermSerializeError::NoTerm)
135        } else {
136            Ok(Term::String(v))
137        }
138    }
139
140    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
141        let v = String::from(v);
142
143        if v.is_empty() {
144            Err(TermSerializeError::NoTerm)
145        } else {
146            Ok(Term::String(v))
147        }
148    }
149
150    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
151        Err(TermSerializeError::NotTerm)
152    }
153
154    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
155        Err(TermSerializeError::NoTerm)
156    }
157
158    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
159    where
160        T: Serialize + ?Sized,
161    {
162        value.serialize(self)
163    }
164
165    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
166        Err(TermSerializeError::NotTerm)
167    }
168
169    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
170        Err(TermSerializeError::NotTerm)
171    }
172
173    fn serialize_unit_variant(
174        self,
175        _name: &'static str,
176        _variant_index: u32,
177        variant: &'static str,
178    ) -> Result<Self::Ok, Self::Error> {
179        self.serialize_str(variant)
180    }
181
182    fn serialize_newtype_struct<T>(
183        self,
184        _name: &'static str,
185        value: &T,
186    ) -> Result<Self::Ok, Self::Error>
187    where
188        T: Serialize + ?Sized,
189    {
190        value.serialize(self)
191    }
192
193    fn serialize_newtype_variant<T>(
194        self,
195        _name: &'static str,
196        _variant_index: u32,
197        _variant: &'static str,
198        _value: &T,
199    ) -> Result<Self::Ok, Self::Error>
200    where
201        T: Serialize + ?Sized,
202    {
203        Err(TermSerializeError::NotTerm)
204    }
205
206    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
207        Err(TermSerializeError::NotTerm)
208    }
209
210    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
211        Err(TermSerializeError::NotTerm)
212    }
213
214    fn serialize_tuple_struct(
215        self,
216        _name: &'static str,
217        _len: usize,
218    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
219        Err(TermSerializeError::NotTerm)
220    }
221
222    fn serialize_tuple_variant(
223        self,
224        _name: &'static str,
225        _variant_index: u32,
226        _variant: &'static str,
227        _len: usize,
228    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
229        Err(TermSerializeError::NotTerm)
230    }
231
232    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
233        Err(TermSerializeError::NotTerm)
234    }
235
236    fn serialize_struct(
237        self,
238        _name: &'static str,
239        _len: usize,
240    ) -> Result<Self::SerializeStruct, Self::Error> {
241        Err(TermSerializeError::NotTerm)
242    }
243
244    fn serialize_struct_variant(
245        self,
246        _name: &'static str,
247        _variant_index: u32,
248        _variant: &'static str,
249        _len: usize,
250    ) -> Result<Self::SerializeStructVariant, Self::Error> {
251        Err(TermSerializeError::NotTerm)
252    }
253}
254
255impl ser::SerializeSeq for Serializer {
256    type Ok = Term;
257    type Error = TermSerializeError;
258
259    fn serialize_element<T>(&mut self, _value: &T) -> Result<(), Self::Error>
260    where
261        T: Serialize + ?Sized,
262    {
263        Err(TermSerializeError::NotTerm)
264    }
265
266    fn end(self) -> Result<Self::Ok, Self::Error> {
267        Err(TermSerializeError::NotTerm)
268    }
269}
270
271impl ser::SerializeTuple for Serializer {
272    type Ok = Term;
273    type Error = TermSerializeError;
274
275    fn serialize_element<T>(&mut self, _value: &T) -> Result<(), Self::Error>
276    where
277        T: Serialize + ?Sized,
278    {
279        Err(TermSerializeError::NotTerm)
280    }
281
282    fn end(self) -> Result<Self::Ok, Self::Error> {
283        Err(TermSerializeError::NotTerm)
284    }
285}
286
287impl ser::SerializeTupleStruct for Serializer {
288    type Ok = Term;
289    type Error = TermSerializeError;
290
291    fn serialize_field<T>(&mut self, _value: &T) -> Result<(), Self::Error>
292    where
293        T: Serialize + ?Sized,
294    {
295        Err(TermSerializeError::NotTerm)
296    }
297
298    fn end(self) -> Result<Self::Ok, Self::Error> {
299        Err(TermSerializeError::NotTerm)
300    }
301}
302impl ser::SerializeTupleVariant for Serializer {
303    type Ok = Term;
304    type Error = TermSerializeError;
305
306    fn serialize_field<T>(&mut self, _value: &T) -> Result<(), Self::Error>
307    where
308        T: Serialize + ?Sized,
309    {
310        Err(TermSerializeError::NotTerm)
311    }
312
313    fn end(self) -> Result<Self::Ok, Self::Error> {
314        Err(TermSerializeError::NotTerm)
315    }
316}
317
318impl ser::SerializeMap for Serializer {
319    type Ok = Term;
320    type Error = TermSerializeError;
321
322    fn serialize_key<T>(&mut self, _key: &T) -> Result<(), Self::Error>
323    where
324        T: Serialize + ?Sized,
325    {
326        Err(TermSerializeError::NotTerm)
327    }
328
329    fn serialize_value<T>(&mut self, _value: &T) -> Result<(), Self::Error>
330    where
331        T: Serialize + ?Sized,
332    {
333        Err(TermSerializeError::NotTerm)
334    }
335
336    fn end(self) -> Result<Self::Ok, Self::Error> {
337        Err(TermSerializeError::NotTerm)
338    }
339}
340
341impl ser::SerializeStruct for Serializer {
342    type Ok = Term;
343    type Error = TermSerializeError;
344
345    fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<(), Self::Error>
346    where
347        T: Serialize + ?Sized,
348    {
349        Err(TermSerializeError::NotTerm)
350    }
351
352    fn end(self) -> Result<Self::Ok, Self::Error> {
353        Err(TermSerializeError::NotTerm)
354    }
355}
356
357impl ser::SerializeStructVariant for Serializer {
358    type Ok = Term;
359    type Error = TermSerializeError;
360
361    fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<(), Self::Error>
362    where
363        T: Serialize + ?Sized,
364    {
365        Err(TermSerializeError::NotTerm)
366    }
367
368    fn end(self) -> Result<Self::Ok, Self::Error> {
369        Err(TermSerializeError::NotTerm)
370    }
371}
372
373/// Term conversion error
374#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
375pub enum TermSerializeError {
376    /// No term provided,
377    NoTerm,
378
379    /// Provided value was not a term
380    NotTerm,
381}
382
383impl std::fmt::Display for TermSerializeError {
384    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
385        match self {
386            Self::NoTerm => "no term was provided".fmt(f),
387            Self::NotTerm => "provided value was not a term".fmt(f),
388        }
389    }
390}
391
392impl std::error::Error for TermSerializeError {}
393
394impl ser::Error for TermSerializeError {
395    fn custom<T>(_msg: T) -> Self
396    where
397        T: std::fmt::Display,
398    {
399        Self::NotTerm
400    }
401}
402
403#[cfg(test)]
404mod tests {
405    use super::*;
406    use chrono::prelude::*;
407
408    #[test]
409    fn serializes_primitives_correctly() {
410        assert_eq!(Term::new(true), Some(Term::Boolean(true)));
411        assert_eq!(Term::new(12345), Some(Term::PositiveNumber(12345)));
412        assert_eq!(Term::new(-1234), Some(Term::NegativeNumber(-1234)));
413        assert_eq!(Term::new(1_f32), Some(Term::Float32(1.0)));
414        assert_eq!(Term::new(1_f64), Some(Term::Float64(1.0)));
415        assert_eq!(Term::new('s'), Some(Term::String("s".into())));
416        assert_eq!(Term::new("str"), Some(Term::String("str".into())));
417        assert_eq!(
418            Term::new(Utc.with_ymd_and_hms(2022, 3, 21, 0, 5, 8).single().unwrap()),
419            Some(Term::String("2022-03-21T00:05:08Z".into()))
420        );
421    }
422
423    #[test]
424    fn serializes_newtypes_correctly() {
425        #[derive(Serialize)]
426        struct Newtype<T>(T);
427
428        assert_eq!(Term::new(Newtype(123)), Some(Term::PositiveNumber(123)));
429    }
430
431    #[test]
432    fn serializes_wrappers_correctly() {
433        struct Wrapper<T> {
434            value: T,
435        }
436
437        impl<T> Serialize for Wrapper<T>
438        where
439            T: Serialize,
440        {
441            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
442            where
443                S: serde::Serializer,
444            {
445                self.value.serialize(serializer)
446            }
447        }
448
449        assert_eq!(
450            Term::new(Wrapper { value: 123 }),
451            Some(Term::PositiveNumber(123))
452        );
453    }
454
455    #[test]
456    fn custom_partial_eq() {
457        assert_eq!(Term::Float32(1.0), Term::Float64(1.0));
458        assert_eq!(Term::Float64(1.0), Term::Float32(1.0));
459    }
460}