Skip to main content

opensearch_dsl/search/params/
term.rs

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