cel_interpreter/
ser.rs

1// The serde_json crate implements a Serializer for its own Value enum, that is
2// almost exactly the same to our Value enum, so this is more or less copied
3// from [serde_json](https://github.com/serde-rs/json/blob/master/src/value/ser.rs),
4// also mentioned in the [serde documentation](https://serde.rs/).
5
6use crate::{objects::Key, Value};
7use serde::{
8    ser::{self, Impossible, SerializeStruct},
9    Serialize,
10};
11use std::{collections::HashMap, fmt::Display, iter::FromIterator, sync::Arc};
12use thiserror::Error;
13
14#[cfg(feature = "chrono")]
15use chrono::FixedOffset;
16
17pub struct Serializer;
18pub struct KeySerializer;
19
20/// A wrapper Duration type which allows conversion to [Value::Duration] for
21/// types using automatic conversion with [serde::Serialize].
22///
23/// # Examples
24///
25/// ```
26/// use cel_interpreter::{Context, Duration, Program};
27/// use serde::Serialize;
28///
29/// #[derive(Serialize)]
30/// struct MyStruct {
31///     dur: Duration,
32/// }
33///
34/// let mut context = Context::default();
35///
36/// // MyStruct will be implicitly serialized into the CEL appropriate types
37/// context
38///     .add_variable(
39///         "foo",
40///         MyStruct {
41///             dur: chrono::Duration::hours(2).into(),
42///         },
43///     )
44///     .unwrap();
45///
46/// let program = Program::compile("foo.dur == duration('2h')").unwrap();
47/// let value = program.execute(&context).unwrap();
48/// assert_eq!(value, true.into());
49/// ```
50#[cfg(feature = "chrono")]
51#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
52pub struct Duration(pub chrono::Duration);
53
54#[cfg(feature = "chrono")]
55impl Duration {
56    // Since serde can't natively represent durations, we serialize a special
57    // newtype to indicate we want to rebuild the duration in the result, while
58    // remaining compatible with most other Serializer implementations.
59    const NAME: &str = "$__cel_private_Duration";
60    const STRUCT_NAME: &str = "Duration";
61    const SECS_FIELD: &str = "secs";
62    const NANOS_FIELD: &str = "nanos";
63}
64
65#[cfg(feature = "chrono")]
66impl From<Duration> for chrono::Duration {
67    fn from(value: Duration) -> Self {
68        value.0
69    }
70}
71
72#[cfg(feature = "chrono")]
73impl From<chrono::Duration> for Duration {
74    fn from(value: chrono::Duration) -> Self {
75        Self(value)
76    }
77}
78
79#[cfg(feature = "chrono")]
80impl ser::Serialize for Duration {
81    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
82    where
83        S: ser::Serializer,
84    {
85        // chrono::Duration's Serialize impl isn't stable yet and relies on
86        // private fields, so attempt to mimic serde's default impl for std
87        // Duration.
88        struct DurationProxy(chrono::Duration);
89        impl Serialize for DurationProxy {
90            fn serialize<S: ser::Serializer>(
91                &self,
92                serializer: S,
93            ) -> std::result::Result<S::Ok, S::Error> {
94                let mut s = serializer.serialize_struct(Duration::STRUCT_NAME, 2)?;
95                s.serialize_field(Duration::SECS_FIELD, &self.0.num_seconds())?;
96                s.serialize_field(
97                    Duration::NANOS_FIELD,
98                    &(self.0.num_nanoseconds().unwrap_or(0) % 1_000_000_000),
99                )?;
100                s.end()
101            }
102        }
103        serializer.serialize_newtype_struct(Self::NAME, &DurationProxy(self.0))
104    }
105}
106
107/// A wrapper Timestamp type which allows conversion to [Value::Timestamp] for
108/// types using automatic conversion with [serde::Serialize].
109///
110/// # Examples
111///
112/// ```
113/// use cel_interpreter::{Context, Timestamp, Program};
114/// use serde::Serialize;
115///
116/// #[derive(Serialize)]
117/// struct MyStruct {
118///     ts: Timestamp,
119/// }
120///
121/// let mut context = Context::default();
122///
123/// // MyStruct will be implicitly serialized into the CEL appropriate types
124/// context
125///     .add_variable(
126///         "foo",
127///         MyStruct {
128///             ts: chrono::DateTime::parse_from_rfc3339("2025-01-01T00:00:00Z")
129///                 .unwrap()
130///                 .into(),
131///         },
132///     )
133///     .unwrap();
134///
135/// let program = Program::compile("foo.ts == timestamp('2025-01-01T00:00:00Z')").unwrap();
136/// let value = program.execute(&context).unwrap();
137/// assert_eq!(value, true.into());
138/// ```
139#[cfg(feature = "chrono")]
140#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
141pub struct Timestamp(pub chrono::DateTime<FixedOffset>);
142
143#[cfg(feature = "chrono")]
144impl Timestamp {
145    // Since serde can't natively represent timestamps, we serialize a special
146    // newtype to indicate we want to rebuild the timestamp in the result,
147    // while remaining compatible with most other Serializer implementations.
148    const NAME: &str = "$__cel_private_Timestamp";
149}
150
151#[cfg(feature = "chrono")]
152impl From<Timestamp> for chrono::DateTime<FixedOffset> {
153    fn from(value: Timestamp) -> Self {
154        value.0
155    }
156}
157
158#[cfg(feature = "chrono")]
159impl From<chrono::DateTime<FixedOffset>> for Timestamp {
160    fn from(value: chrono::DateTime<FixedOffset>) -> Self {
161        Self(value)
162    }
163}
164
165#[cfg(feature = "chrono")]
166impl ser::Serialize for Timestamp {
167    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
168    where
169        S: ser::Serializer,
170    {
171        serializer.serialize_newtype_struct(Self::NAME, &self.0)
172    }
173}
174
175#[derive(Error, Debug, PartialEq, Clone)]
176pub enum SerializationError {
177    InvalidKey(String),
178    SerdeError(String),
179}
180
181impl ser::Error for SerializationError {
182    fn custom<T>(msg: T) -> Self
183    where
184        T: std::fmt::Display,
185    {
186        SerializationError::SerdeError(msg.to_string())
187    }
188}
189
190impl Display for SerializationError {
191    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
192        match self {
193            SerializationError::SerdeError(msg) => formatter.write_str(msg),
194            SerializationError::InvalidKey(msg) => formatter.write_str(msg),
195        }
196    }
197}
198
199pub type Result<T> = std::result::Result<T, SerializationError>;
200
201pub fn to_value<T>(value: T) -> Result<Value>
202where
203    T: Serialize,
204{
205    value.serialize(Serializer)
206}
207
208impl ser::Serializer for Serializer {
209    type Ok = Value;
210    type Error = SerializationError;
211
212    type SerializeSeq = SerializeVec;
213    type SerializeTuple = SerializeVec;
214    type SerializeTupleStruct = SerializeVec;
215    type SerializeTupleVariant = SerializeTupleVariant;
216    type SerializeMap = SerializeMap;
217    type SerializeStruct = SerializeMap;
218    type SerializeStructVariant = SerializeStructVariant;
219
220    fn serialize_bool(self, v: bool) -> Result<Value> {
221        Ok(Value::Bool(v))
222    }
223
224    fn serialize_i8(self, v: i8) -> Result<Value> {
225        self.serialize_i64(i64::from(v))
226    }
227
228    fn serialize_i16(self, v: i16) -> Result<Value> {
229        self.serialize_i64(i64::from(v))
230    }
231
232    fn serialize_i32(self, v: i32) -> Result<Value> {
233        self.serialize_i64(i64::from(v))
234    }
235
236    fn serialize_i64(self, v: i64) -> Result<Value> {
237        Ok(Value::Int(v))
238    }
239
240    fn serialize_u8(self, v: u8) -> Result<Value> {
241        self.serialize_u64(u64::from(v))
242    }
243
244    fn serialize_u16(self, v: u16) -> Result<Value> {
245        self.serialize_u64(u64::from(v))
246    }
247
248    fn serialize_u32(self, v: u32) -> Result<Value> {
249        self.serialize_u64(u64::from(v))
250    }
251
252    fn serialize_u64(self, v: u64) -> Result<Value> {
253        Ok(Value::UInt(v))
254    }
255
256    fn serialize_f32(self, v: f32) -> Result<Value> {
257        self.serialize_f64(f64::from(v))
258    }
259
260    fn serialize_f64(self, v: f64) -> Result<Value> {
261        Ok(Value::Float(v))
262    }
263
264    fn serialize_char(self, v: char) -> Result<Value> {
265        self.serialize_str(&v.to_string())
266    }
267
268    fn serialize_str(self, v: &str) -> Result<Value> {
269        Ok(Value::String(Arc::new(v.to_string())))
270    }
271
272    fn serialize_bytes(self, v: &[u8]) -> Result<Value> {
273        Ok(Value::Bytes(Arc::new(v.to_vec())))
274    }
275
276    fn serialize_none(self) -> Result<Value> {
277        self.serialize_unit()
278    }
279
280    fn serialize_some<T>(self, value: &T) -> Result<Value>
281    where
282        T: ?Sized + Serialize,
283    {
284        value.serialize(self)
285    }
286
287    fn serialize_unit(self) -> Result<Value> {
288        Ok(Value::Null)
289    }
290
291    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
292        self.serialize_unit()
293    }
294
295    fn serialize_unit_variant(
296        self,
297        _name: &'static str,
298        _variant_index: u32,
299        variant: &'static str,
300    ) -> Result<Value> {
301        self.serialize_str(variant)
302    }
303
304    fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Value>
305    where
306        T: ?Sized + Serialize,
307    {
308        match name {
309            #[cfg(feature = "chrono")]
310            Duration::NAME => value.serialize(TimeSerializer::Duration),
311            #[cfg(feature = "chrono")]
312            Timestamp::NAME => value.serialize(TimeSerializer::Timestamp),
313            _ => value.serialize(self),
314        }
315    }
316
317    fn serialize_newtype_variant<T>(
318        self,
319        _name: &'static str,
320        _variant_index: u32,
321        variant: &'static str,
322        value: &T,
323    ) -> Result<Value>
324    where
325        T: ?Sized + Serialize,
326    {
327        Ok(HashMap::from_iter([(variant.to_string(), value.serialize(Serializer)?)]).into())
328    }
329
330    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
331        Ok(SerializeVec {
332            vec: Vec::with_capacity(_len.unwrap_or(0)),
333        })
334    }
335
336    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
337        self.serialize_seq(Some(len))
338    }
339
340    fn serialize_tuple_struct(
341        self,
342        _name: &'static str,
343        len: usize,
344    ) -> Result<Self::SerializeTupleStruct> {
345        self.serialize_seq(Some(len))
346    }
347
348    fn serialize_tuple_variant(
349        self,
350        _name: &'static str,
351        _variant_index: u32,
352        variant: &'static str,
353        _len: usize,
354    ) -> Result<Self::SerializeTupleVariant> {
355        Ok(SerializeTupleVariant {
356            name: String::from(variant),
357            vec: Vec::with_capacity(_len),
358        })
359    }
360
361    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
362        Ok(SerializeMap {
363            map: HashMap::new(),
364            next_key: None,
365        })
366    }
367
368    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
369        self.serialize_map(Some(len))
370    }
371
372    fn serialize_struct_variant(
373        self,
374        _name: &'static str,
375        _variant_index: u32,
376        variant: &'static str,
377        _len: usize,
378    ) -> Result<Self::SerializeStructVariant> {
379        Ok(SerializeStructVariant {
380            name: String::from(variant),
381            map: HashMap::new(),
382        })
383    }
384}
385
386pub struct SerializeVec {
387    vec: Vec<Value>,
388}
389
390pub struct SerializeTupleVariant {
391    name: String,
392    vec: Vec<Value>,
393}
394
395pub struct SerializeMap {
396    map: HashMap<Key, Value>,
397    next_key: Option<Key>,
398}
399
400pub struct SerializeStructVariant {
401    name: String,
402    map: HashMap<Key, Value>,
403}
404
405#[cfg(feature = "chrono")]
406#[derive(Debug, Default)]
407struct SerializeTimestamp {
408    secs: i64,
409    nanos: i32,
410}
411
412impl ser::SerializeSeq for SerializeVec {
413    type Ok = Value;
414    type Error = SerializationError;
415
416    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
417    where
418        T: ?Sized + Serialize,
419    {
420        self.vec.push(to_value(value)?);
421        Ok(())
422    }
423
424    fn end(self) -> Result<Value> {
425        Ok(Value::List(Arc::new(self.vec)))
426    }
427}
428
429impl ser::SerializeTuple for SerializeVec {
430    type Ok = Value;
431    type Error = SerializationError;
432
433    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
434    where
435        T: ?Sized + Serialize,
436    {
437        serde::ser::SerializeSeq::serialize_element(self, value)
438    }
439
440    fn end(self) -> Result<Value> {
441        serde::ser::SerializeSeq::end(self)
442    }
443}
444
445impl ser::SerializeTupleStruct for SerializeVec {
446    type Ok = Value;
447    type Error = SerializationError;
448
449    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
450    where
451        T: ?Sized + Serialize,
452    {
453        serde::ser::SerializeSeq::serialize_element(self, value)
454    }
455
456    fn end(self) -> Result<Value> {
457        serde::ser::SerializeSeq::end(self)
458    }
459}
460
461impl ser::SerializeTupleVariant for SerializeTupleVariant {
462    type Ok = Value;
463    type Error = SerializationError;
464
465    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
466    where
467        T: ?Sized + Serialize,
468    {
469        self.vec.push(to_value(value)?);
470        Ok(())
471    }
472
473    fn end(self) -> Result<Value> {
474        let map = HashMap::from_iter([(self.name, Arc::new(self.vec))]);
475        Ok(map.into())
476    }
477}
478
479impl ser::SerializeMap for SerializeMap {
480    type Ok = Value;
481    type Error = SerializationError;
482
483    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
484    where
485        T: ?Sized + Serialize,
486    {
487        self.next_key = Some(key.serialize(KeySerializer)?);
488        Ok(())
489    }
490
491    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
492    where
493        T: ?Sized + Serialize,
494    {
495        self.map.insert(
496            self.next_key.clone().ok_or_else(|| {
497                SerializationError::InvalidKey(
498                    "serialize_value called before serialize_key".to_string(),
499                )
500            })?,
501            value.serialize(Serializer)?,
502        );
503        Ok(())
504    }
505
506    fn end(self) -> Result<Value> {
507        Ok(self.map.into())
508    }
509}
510
511impl ser::SerializeStruct for SerializeMap {
512    type Ok = Value;
513    type Error = SerializationError;
514
515    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
516    where
517        T: ?Sized + Serialize,
518    {
519        serde::ser::SerializeMap::serialize_entry(self, key, value)
520    }
521
522    fn end(self) -> Result<Value> {
523        serde::ser::SerializeMap::end(self)
524    }
525}
526
527impl ser::SerializeStructVariant for SerializeStructVariant {
528    type Ok = Value;
529    type Error = SerializationError;
530
531    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
532    where
533        T: ?Sized + Serialize,
534    {
535        self.map
536            .insert(key.serialize(KeySerializer)?, to_value(value)?);
537        Ok(())
538    }
539
540    fn end(self) -> Result<Value> {
541        let map: HashMap<String, Value> = HashMap::from_iter([(self.name, self.map.into())]);
542        Ok(map.into())
543    }
544}
545
546#[cfg(feature = "chrono")]
547impl ser::SerializeStruct for SerializeTimestamp {
548    type Ok = Value;
549    type Error = SerializationError;
550    fn serialize_field<T>(
551        &mut self,
552        key: &'static str,
553        value: &T,
554    ) -> std::result::Result<(), Self::Error>
555    where
556        T: ?Sized + Serialize,
557    {
558        match key {
559            Duration::SECS_FIELD => {
560                let Value::Int(val) = value.serialize(Serializer)? else {
561                    return Err(SerializationError::SerdeError(
562                        "invalid type of value in timestamp struct".to_owned(),
563                    ));
564                };
565                self.secs = val;
566                Ok(())
567            }
568            Duration::NANOS_FIELD => {
569                let Value::Int(val) = value.serialize(Serializer)? else {
570                    return Err(SerializationError::SerdeError(
571                        "invalid type of value in timestamp struct".to_owned(),
572                    ));
573                };
574                self.nanos = val.try_into().map_err(|_| {
575                    SerializationError::SerdeError(
576                        "timestamp struct nanos field is invalid".to_owned(),
577                    )
578                })?;
579                Ok(())
580            }
581            _ => Err(SerializationError::SerdeError(
582                "invalid field in duration struct".to_owned(),
583            )),
584        }
585    }
586
587    fn end(self) -> std::result::Result<Self::Ok, Self::Error> {
588        Ok(chrono::Duration::seconds(self.secs)
589            .checked_add(&chrono::Duration::nanoseconds(self.nanos.into()))
590            .unwrap()
591            .into())
592    }
593}
594
595impl ser::Serializer for KeySerializer {
596    type Ok = Key;
597    type Error = SerializationError;
598
599    type SerializeSeq = Impossible<Key, SerializationError>;
600    type SerializeTuple = Impossible<Key, SerializationError>;
601    type SerializeTupleStruct = Impossible<Key, SerializationError>;
602    type SerializeTupleVariant = Impossible<Key, SerializationError>;
603    type SerializeMap = Impossible<Key, SerializationError>;
604    type SerializeStruct = Impossible<Key, SerializationError>;
605    type SerializeStructVariant = Impossible<Key, SerializationError>;
606
607    fn serialize_bool(self, v: bool) -> Result<Key> {
608        Ok(Key::Bool(v))
609    }
610
611    fn serialize_i8(self, v: i8) -> Result<Key> {
612        self.serialize_i64(i64::from(v))
613    }
614
615    fn serialize_i16(self, v: i16) -> Result<Key> {
616        self.serialize_i64(i64::from(v))
617    }
618
619    fn serialize_i32(self, v: i32) -> Result<Key> {
620        self.serialize_i64(i64::from(v))
621    }
622
623    fn serialize_i64(self, v: i64) -> Result<Key> {
624        Ok(Key::Int(v))
625    }
626
627    fn serialize_u8(self, v: u8) -> Result<Key> {
628        self.serialize_u64(u64::from(v))
629    }
630
631    fn serialize_u16(self, v: u16) -> Result<Key> {
632        self.serialize_u64(u64::from(v))
633    }
634
635    fn serialize_u32(self, v: u32) -> Result<Key> {
636        self.serialize_u64(u64::from(v))
637    }
638
639    fn serialize_u64(self, v: u64) -> Result<Key> {
640        Ok(Key::Uint(v))
641    }
642
643    fn serialize_f32(self, _v: f32) -> Result<Key> {
644        Err(SerializationError::InvalidKey(
645            "Float is not supported".to_string(),
646        ))
647    }
648
649    fn serialize_f64(self, _v: f64) -> Result<Key> {
650        Err(SerializationError::InvalidKey(
651            "Float is not supported".to_string(),
652        ))
653    }
654
655    fn serialize_char(self, v: char) -> Result<Key> {
656        self.serialize_str(&v.to_string())
657    }
658
659    fn serialize_str(self, v: &str) -> Result<Key> {
660        Ok(Key::String(Arc::new(v.to_string())))
661    }
662
663    fn serialize_bytes(self, _v: &[u8]) -> Result<Key> {
664        Err(SerializationError::InvalidKey(
665            "Bytes are not supported".to_string(),
666        ))
667    }
668
669    fn serialize_none(self) -> Result<Key> {
670        Err(SerializationError::InvalidKey(
671            "None is not supported".to_string(),
672        ))
673    }
674
675    fn serialize_some<T>(self, value: &T) -> Result<Key>
676    where
677        T: ?Sized + Serialize,
678    {
679        value.serialize(self)
680    }
681
682    fn serialize_unit(self) -> Result<Key> {
683        Err(SerializationError::InvalidKey(
684            "Null is not supported".to_string(),
685        ))
686    }
687
688    fn serialize_unit_struct(self, _name: &'static str) -> Result<Key> {
689        Err(SerializationError::InvalidKey(
690            "Empty unit structs are not supported".to_string(),
691        ))
692    }
693
694    fn serialize_unit_variant(
695        self,
696        _name: &'static str,
697        _variant_index: u32,
698        variant: &'static str,
699    ) -> Result<Key> {
700        Ok(Key::String(Arc::new(variant.to_string())))
701    }
702
703    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Key>
704    where
705        T: ?Sized + Serialize,
706    {
707        value.serialize(KeySerializer)
708    }
709
710    fn serialize_newtype_variant<T>(
711        self,
712        _name: &'static str,
713        _variant_index: u32,
714        _variant: &'static str,
715        _value: &T,
716    ) -> Result<Key>
717    where
718        T: ?Sized + Serialize,
719    {
720        Err(SerializationError::InvalidKey(
721            "Newtype variant is not supported".to_string(),
722        ))
723    }
724
725    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
726        Err(SerializationError::InvalidKey(
727            "Sequences are not supported".to_string(),
728        ))
729    }
730
731    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
732        Err(SerializationError::InvalidKey(
733            "Tuples are not supported".to_string(),
734        ))
735    }
736
737    fn serialize_tuple_struct(
738        self,
739        _name: &'static str,
740        _len: usize,
741    ) -> Result<Self::SerializeTupleStruct> {
742        Err(SerializationError::InvalidKey(
743            "Structs are not supported".to_string(),
744        ))
745    }
746
747    fn serialize_tuple_variant(
748        self,
749        _name: &'static str,
750        _variant_index: u32,
751        _variant: &'static str,
752        _len: usize,
753    ) -> Result<Self::SerializeTupleVariant> {
754        Err(SerializationError::InvalidKey(
755            "Tuple variants are not supported".to_string(),
756        ))
757    }
758
759    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
760        Err(SerializationError::InvalidKey(
761            "Map variants are not supported".to_string(),
762        ))
763    }
764
765    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
766        Err(SerializationError::InvalidKey(
767            "Structs are not supported".to_string(),
768        ))
769    }
770
771    fn serialize_struct_variant(
772        self,
773        _name: &'static str,
774        _variant_index: u32,
775        _variant: &'static str,
776        _len: usize,
777    ) -> Result<Self::SerializeStructVariant> {
778        Err(SerializationError::InvalidKey(
779            "Struct variants are not supported".to_string(),
780        ))
781    }
782}
783
784#[cfg(feature = "chrono")]
785#[derive(Debug)]
786enum TimeSerializer {
787    Duration,
788    Timestamp,
789}
790
791#[cfg(feature = "chrono")]
792impl ser::Serializer for TimeSerializer {
793    type Ok = Value;
794    type Error = SerializationError;
795
796    type SerializeStruct = SerializeTimestamp;
797
798    // Should never be used, so just reuse existing.
799    type SerializeSeq = SerializeVec;
800    type SerializeTuple = SerializeVec;
801    type SerializeTupleStruct = SerializeVec;
802    type SerializeTupleVariant = SerializeTupleVariant;
803    type SerializeMap = SerializeMap;
804    type SerializeStructVariant = SerializeStructVariant;
805
806    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
807        if !matches!(self, Self::Duration { .. }) || name != Duration::STRUCT_NAME {
808            return Err(SerializationError::SerdeError(
809                "expected Duration struct with Duration marker newtype struct".to_owned(),
810            ));
811        }
812        if len != 2 {
813            return Err(SerializationError::SerdeError(
814                "expected Duration struct to have 2 fields".to_owned(),
815            ));
816        }
817        Ok(SerializeTimestamp::default())
818    }
819
820    fn serialize_str(self, v: &str) -> Result<Value> {
821        if !matches!(self, Self::Timestamp) {
822            return Err(SerializationError::SerdeError(
823                "expected Timestamp string with Timestamp marker newtype struct".to_owned(),
824            ));
825        }
826        Ok(v.parse::<chrono::DateTime<FixedOffset>>()
827            .map_err(|e| SerializationError::SerdeError(e.to_string()))?
828            .into())
829    }
830
831    fn serialize_bool(self, _v: bool) -> Result<Value> {
832        unreachable!()
833    }
834
835    fn serialize_i8(self, _v: i8) -> Result<Value> {
836        unreachable!()
837    }
838
839    fn serialize_i16(self, _v: i16) -> Result<Value> {
840        unreachable!()
841    }
842
843    fn serialize_i32(self, _v: i32) -> Result<Value> {
844        unreachable!()
845    }
846
847    fn serialize_i64(self, _v: i64) -> Result<Value> {
848        unreachable!()
849    }
850
851    fn serialize_u8(self, _v: u8) -> Result<Value> {
852        unreachable!()
853    }
854
855    fn serialize_u16(self, _v: u16) -> Result<Value> {
856        unreachable!()
857    }
858
859    fn serialize_u32(self, _v: u32) -> Result<Value> {
860        unreachable!()
861    }
862
863    fn serialize_u64(self, _v: u64) -> Result<Value> {
864        unreachable!()
865    }
866
867    fn serialize_f32(self, _v: f32) -> Result<Value> {
868        unreachable!()
869    }
870
871    fn serialize_f64(self, _v: f64) -> Result<Value> {
872        unreachable!()
873    }
874
875    fn serialize_char(self, _v: char) -> Result<Value> {
876        unreachable!()
877    }
878
879    fn serialize_bytes(self, _v: &[u8]) -> Result<Value> {
880        unreachable!()
881    }
882
883    fn serialize_none(self) -> Result<Value> {
884        unreachable!()
885    }
886
887    fn serialize_some<T>(self, _value: &T) -> Result<Value>
888    where
889        T: ?Sized + Serialize,
890    {
891        unreachable!()
892    }
893
894    fn serialize_unit(self) -> Result<Value> {
895        unreachable!()
896    }
897
898    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
899        unreachable!()
900    }
901
902    fn serialize_unit_variant(
903        self,
904        _name: &'static str,
905        _variant_index: u32,
906        _variant: &'static str,
907    ) -> Result<Value> {
908        unreachable!()
909    }
910
911    fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<Value>
912    where
913        T: ?Sized + Serialize,
914    {
915        unreachable!()
916    }
917
918    fn serialize_newtype_variant<T>(
919        self,
920        _name: &'static str,
921        _variant_index: u32,
922        _variant: &'static str,
923        _value: &T,
924    ) -> Result<Value>
925    where
926        T: ?Sized + Serialize,
927    {
928        unreachable!()
929    }
930
931    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
932        unreachable!()
933    }
934
935    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
936        unreachable!()
937    }
938
939    fn serialize_tuple_struct(
940        self,
941        _name: &'static str,
942        _len: usize,
943    ) -> Result<Self::SerializeTupleStruct> {
944        unreachable!()
945    }
946
947    fn serialize_tuple_variant(
948        self,
949        _name: &'static str,
950        _variant_index: u32,
951        _variant: &'static str,
952        _len: usize,
953    ) -> Result<Self::SerializeTupleVariant> {
954        unreachable!()
955    }
956
957    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
958        unreachable!()
959    }
960
961    fn serialize_struct_variant(
962        self,
963        _name: &'static str,
964        _variant_index: u32,
965        _variant: &'static str,
966        _len: usize,
967    ) -> Result<Self::SerializeStructVariant> {
968        unreachable!()
969    }
970}
971
972#[cfg(test)]
973mod tests {
974    use crate::{objects::Key, to_value, Value};
975    use crate::{Context, Program};
976    use serde::Serialize;
977    use serde_bytes::Bytes;
978    use std::{collections::HashMap, iter::FromIterator, sync::Arc};
979
980    #[cfg(feature = "chrono")]
981    use super::{Duration, Timestamp};
982
983    macro_rules! primitive_test {
984        ($functionName:ident, $strValue: literal, $value: expr) => {
985            #[test]
986            fn $functionName() {
987                let program = Program::compile($strValue).unwrap();
988                let result = program.execute(&Context::default());
989                assert_eq!(Value::from($value), result.unwrap());
990            }
991        };
992    }
993
994    primitive_test!(test_u64_zero, "0u", 0_u64);
995    primitive_test!(test_i64_zero, "0", 0_i64);
996    primitive_test!(test_f64_zero, "0.0", 0_f64);
997    //primitive_test!(test_f64_zero, "0.", 0_f64); this test fails
998    primitive_test!(test_bool_false, "false", false);
999    primitive_test!(test_bool_true, "true", true);
1000    primitive_test!(test_string_empty, "\"\"", "");
1001    primitive_test!(test_string_non_empty, "\"test\"", "test");
1002    primitive_test!(test_byte_ones, r#"b"\001\001""#, vec!(1_u8, 1_u8));
1003    // primitive_test!(test_triple_double_quoted_string, #"r"""""""#, "");
1004    // primitive_test!(test_triple_single_quoted_string, "r''''''", "");
1005    primitive_test!(test_utf8_character_as_bytes, "b'ΓΏ'", vec!(195_u8, 191_u8));
1006
1007    #[test]
1008    fn test_json_data_conversion() {
1009        #[derive(Serialize)]
1010        struct TestPrimitives {
1011            bool: bool,
1012            u8: u8,
1013            u16: u16,
1014            u32: u32,
1015            u64: u64,
1016            int8: i8,
1017            int16: i16,
1018            int32: i32,
1019            int64: i64,
1020            f32: f32,
1021            f64: f64,
1022            char: char,
1023            string: String,
1024            bytes: &'static Bytes,
1025        }
1026
1027        let test = TestPrimitives {
1028            bool: true,
1029            int8: 8_i8,
1030            int16: 16_i16,
1031            int32: 32_i32,
1032            int64: 64_i64,
1033            u8: 8_u8,
1034            u16: 16_u16,
1035            u32: 32_u32,
1036            u64: 64_u64,
1037            f32: 0.32_f32,
1038            f64: 0.64_f64,
1039            char: 'a',
1040            string: "string".to_string(),
1041            bytes: Bytes::new(&[1_u8, 1_u8, 1_u8, 1_u8]),
1042        };
1043
1044        let serialized = to_value(test).unwrap();
1045        let expected: Value = HashMap::from_iter([
1046            (Key::String(Arc::new("bool".to_string())), Value::Bool(true)),
1047            (Key::String(Arc::new("int8".to_string())), Value::Int(8)),
1048            (Key::String(Arc::new("int16".to_string())), Value::Int(16)),
1049            (Key::String(Arc::new("int32".to_string())), Value::Int(32)),
1050            (Key::String(Arc::new("int64".to_string())), Value::Int(64)),
1051            (Key::String(Arc::new("u8".to_string())), Value::UInt(8)),
1052            (Key::String(Arc::new("u16".to_string())), Value::UInt(16)),
1053            (Key::String(Arc::new("u32".to_string())), Value::UInt(32)),
1054            (Key::String(Arc::new("u64".to_string())), Value::UInt(64)),
1055            (
1056                Key::String(Arc::new("f32".to_string())),
1057                Value::Float(f64::from(0.32_f32)),
1058            ),
1059            (Key::String(Arc::new("f64".to_string())), Value::Float(0.64)),
1060            (
1061                Key::String(Arc::new("char".to_string())),
1062                Value::String(Arc::new("a".to_string())),
1063            ),
1064            (
1065                Key::String(Arc::new("string".to_string())),
1066                Value::String(Arc::new("string".to_string())),
1067            ),
1068            (
1069                Key::String(Arc::new("bytes".to_string())),
1070                Value::Bytes(Arc::new(vec![1, 1, 1, 1])),
1071            ),
1072        ])
1073        .into();
1074
1075        // Test with CEL because iterator is not implemented for Value::Map
1076        let program =
1077            Program::compile("expected.all(key, serialized[key] == expected[key])").unwrap();
1078        let mut context = Context::default();
1079        context.add_variable("expected", expected).unwrap();
1080        context.add_variable("serialized", serialized).unwrap();
1081        let value = program.execute(&context).unwrap();
1082        assert_eq!(value, true.into())
1083    }
1084
1085    #[derive(Serialize)]
1086    enum TestCompoundTypes {
1087        Unit,
1088        Newtype(u32),
1089        Wrapped(Option<u8>),
1090        Tuple(u32, u32),
1091        Struct {
1092            a: i32,
1093            nested: HashMap<bool, HashMap<String, Vec<String>>>,
1094        },
1095        Map(HashMap<String, &'static Bytes>),
1096    }
1097    #[test]
1098    fn test_unit() {
1099        let unit = to_value(TestCompoundTypes::Unit).unwrap();
1100        let expected: Value = "Unit".into();
1101        let program = Program::compile("test == expected").unwrap();
1102        let mut context = Context::default();
1103        context.add_variable("expected", expected).unwrap();
1104        context.add_variable("test", unit).unwrap();
1105        let value = program.execute(&context).unwrap();
1106        assert_eq!(value, true.into())
1107    }
1108    #[test]
1109    fn test_newtype() {
1110        let newtype = to_value(TestCompoundTypes::Newtype(32)).unwrap();
1111        let expected: Value = HashMap::from([("Newtype", Value::UInt(32))]).into();
1112        let program = Program::compile("test == expected").unwrap();
1113        let mut context = Context::default();
1114        context.add_variable("expected", expected).unwrap();
1115        context.add_variable("test", newtype).unwrap();
1116        let value = program.execute(&context).unwrap();
1117        assert_eq!(value, true.into())
1118    }
1119    #[test]
1120    fn test_options() {
1121        // Test Option serialization
1122        let wrapped = to_value(TestCompoundTypes::Wrapped(None)).unwrap();
1123        let expected: Value = HashMap::from([("Wrapped", Value::Null)]).into();
1124        let program = Program::compile("test == expected").unwrap();
1125        let mut context = Context::default();
1126        context.add_variable("expected", expected).unwrap();
1127        context.add_variable("test", wrapped).unwrap();
1128        let value = program.execute(&context).unwrap();
1129        assert_eq!(value, true.into());
1130
1131        let wrapped = to_value(TestCompoundTypes::Wrapped(Some(8))).unwrap();
1132        let expected: Value = HashMap::from([("Wrapped", Value::UInt(8))]).into();
1133        let program = Program::compile("test == expected").unwrap();
1134        let mut context = Context::default();
1135        context.add_variable("expected", expected).unwrap();
1136        context.add_variable("test", wrapped).unwrap();
1137        let value = program.execute(&context).unwrap();
1138        assert_eq!(value, true.into())
1139    }
1140
1141    #[test]
1142    fn test_tuples() {
1143        // Test Tuple serialization
1144        let tuple = to_value(TestCompoundTypes::Tuple(12, 16)).unwrap();
1145        let expected: Value = HashMap::from([(
1146            "Tuple",
1147            Value::List(Arc::new(vec![12_u64.into(), 16_u64.into()])),
1148        )])
1149        .into();
1150        let program = Program::compile("test == expected").unwrap();
1151        let mut context = Context::default();
1152        context.add_variable("expected", expected).unwrap();
1153        context.add_variable("test", tuple).unwrap();
1154        let value = program.execute(&context).unwrap();
1155        assert_eq!(value, true.into())
1156    }
1157
1158    #[test]
1159    fn test_structs() {
1160        // Test Struct serialization
1161        let test_struct = TestCompoundTypes::Struct {
1162            a: 32_i32,
1163            nested: HashMap::from_iter([(
1164                true,
1165                HashMap::from_iter([(
1166                    "Test".to_string(),
1167                    vec!["a".to_string(), "b".to_string(), "c".to_string()],
1168                )]),
1169            )]),
1170        };
1171        let expected: Value = HashMap::<Key, Value>::from([(
1172            "Struct".into(),
1173            HashMap::<Key, Value>::from_iter([
1174                ("a".into(), 32_i32.into()),
1175                (
1176                    "nested".into(),
1177                    HashMap::<Key, Value>::from_iter([(
1178                        true.into(),
1179                        HashMap::<Key, Value>::from_iter([(
1180                            "Test".into(),
1181                            vec!["a".to_string(), "b".to_string(), "c".to_string()].into(),
1182                        )])
1183                        .into(),
1184                    )])
1185                    .into(),
1186                ),
1187            ])
1188            .into(),
1189        )])
1190        .into();
1191        let program = Program::compile("expected.all(key, test[key] == expected[key])").unwrap();
1192        let mut context = Context::default();
1193        context.add_variable("expected", expected).unwrap();
1194        context.add_variable("test", test_struct).unwrap();
1195        let value = program.execute(&context).unwrap();
1196        assert_eq!(value, true.into());
1197    }
1198
1199    #[test]
1200    fn test_maps() {
1201        // Test Map serialization
1202        let map = to_value(TestCompoundTypes::Map(
1203            HashMap::<String, &'static Bytes>::from_iter([(
1204                "Test".to_string(),
1205                Bytes::new(&[0_u8, 0_u8, 0_u8, 0_u8]),
1206            )]),
1207        ))
1208        .unwrap();
1209        let expected: Value = HashMap::from([(
1210            "Map",
1211            HashMap::<Key, Value>::from_iter([(
1212                "Test".into(),
1213                Value::Bytes(Arc::new(vec![0_u8, 0_u8, 0_u8, 0_u8])),
1214            )]),
1215        )])
1216        .into();
1217        assert_eq!(map, expected)
1218    }
1219
1220    #[cfg(feature = "chrono")]
1221    #[derive(Serialize)]
1222    struct TestTimeTypes {
1223        dur: Duration,
1224        ts: Timestamp,
1225    }
1226
1227    #[cfg(feature = "chrono")]
1228    #[test]
1229    fn test_time_types() {
1230        use chrono::FixedOffset;
1231
1232        let tests = to_value([
1233            TestTimeTypes {
1234                dur: chrono::Duration::milliseconds(1527).into(),
1235                ts: chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00")
1236                    .unwrap()
1237                    .into(),
1238            },
1239            // Let's test chrono::Duration's particular handling around math
1240            // and negatives and timestamps from BCE.
1241            TestTimeTypes {
1242                dur: chrono::Duration::milliseconds(-1527).into(),
1243                ts: "-0001-12-01T00:00:00-08:00"
1244                    .parse::<chrono::DateTime<FixedOffset>>()
1245                    .unwrap()
1246                    .into(),
1247            },
1248            TestTimeTypes {
1249                dur: (chrono::Duration::seconds(1) - chrono::Duration::nanoseconds(1000000001))
1250                    .into(),
1251                ts: chrono::DateTime::parse_from_rfc3339("0001-12-01T00:00:00+08:00")
1252                    .unwrap()
1253                    .into(),
1254            },
1255            TestTimeTypes {
1256                dur: (chrono::Duration::seconds(-1) + chrono::Duration::nanoseconds(1000000001))
1257                    .into(),
1258                ts: chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00")
1259                    .unwrap()
1260                    .into(),
1261            },
1262        ])
1263        .unwrap();
1264        let expected: Value = vec![
1265            Value::Map(
1266                HashMap::<_, Value>::from([
1267                    ("dur", chrono::Duration::milliseconds(1527).into()),
1268                    (
1269                        "ts",
1270                        chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00")
1271                            .unwrap()
1272                            .into(),
1273                    ),
1274                ])
1275                .into(),
1276            ),
1277            Value::Map(
1278                HashMap::<_, Value>::from([
1279                    ("dur", chrono::Duration::nanoseconds(-1527000000).into()),
1280                    (
1281                        "ts",
1282                        "-0001-12-01T00:00:00-08:00"
1283                            .parse::<chrono::DateTime<FixedOffset>>()
1284                            .unwrap()
1285                            .into(),
1286                    ),
1287                ])
1288                .into(),
1289            ),
1290            Value::Map(
1291                HashMap::<_, Value>::from([
1292                    ("dur", chrono::Duration::nanoseconds(-1).into()),
1293                    (
1294                        "ts",
1295                        chrono::DateTime::parse_from_rfc3339("0001-12-01T00:00:00+08:00")
1296                            .unwrap()
1297                            .into(),
1298                    ),
1299                ])
1300                .into(),
1301            ),
1302            Value::Map(
1303                HashMap::<_, Value>::from([
1304                    ("dur", chrono::Duration::nanoseconds(1).into()),
1305                    (
1306                        "ts",
1307                        chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00")
1308                            .unwrap()
1309                            .into(),
1310                    ),
1311                ])
1312                .into(),
1313            ),
1314        ]
1315        .into();
1316        assert_eq!(tests, expected);
1317
1318        let program = Program::compile("test == expected").unwrap();
1319        let mut context = Context::default();
1320        context.add_variable("expected", expected).unwrap();
1321        context.add_variable("test", tests).unwrap();
1322        let value = program.execute(&context).unwrap();
1323        assert_eq!(value, true.into());
1324    }
1325
1326    #[cfg(feature = "chrono")]
1327    #[cfg(feature = "json")]
1328    #[test]
1329    fn test_time_json() {
1330        use chrono::FixedOffset;
1331
1332        // Test that Durations and Timestamps serialize correctly with
1333        // serde_json.
1334        let tests = [
1335            TestTimeTypes {
1336                dur: chrono::Duration::milliseconds(1527).into(),
1337                ts: chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00")
1338                    .unwrap()
1339                    .into(),
1340            },
1341            TestTimeTypes {
1342                dur: chrono::Duration::milliseconds(-1527).into(),
1343                ts: "-0001-12-01T00:00:00-08:00"
1344                    .parse::<chrono::DateTime<FixedOffset>>()
1345                    .unwrap()
1346                    .into(),
1347            },
1348            TestTimeTypes {
1349                dur: (chrono::Duration::seconds(1) - chrono::Duration::nanoseconds(1000000001))
1350                    .into(),
1351                ts: chrono::DateTime::parse_from_rfc3339("0001-12-01T00:00:00+08:00")
1352                    .unwrap()
1353                    .into(),
1354            },
1355            TestTimeTypes {
1356                dur: (chrono::Duration::seconds(-1) + chrono::Duration::nanoseconds(1000000001))
1357                    .into(),
1358                ts: chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00")
1359                    .unwrap()
1360                    .into(),
1361            },
1362        ];
1363
1364        let expect = "[\
1365{\"dur\":{\"secs\":1,\"nanos\":527000000},\"ts\":\"1996-12-19T16:39:57-08:00\"},\
1366{\"dur\":{\"secs\":-1,\"nanos\":-527000000},\"ts\":\"-0001-12-01T00:00:00-08:00\"},\
1367{\"dur\":{\"secs\":0,\"nanos\":-1},\"ts\":\"0001-12-01T00:00:00+08:00\"},\
1368{\"dur\":{\"secs\":0,\"nanos\":1},\"ts\":\"1996-12-19T16:39:57-08:00\"}\
1369]";
1370        let actual = serde_json::to_string(&tests).unwrap();
1371        assert_eq!(actual, expect);
1372    }
1373}