Skip to main content

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