Skip to main content

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