jmespath/
variable.rs

1//! Module for JMESPath runtime variables.
2
3use serde::de::IntoDeserializer;
4use serde::*;
5use serde_json::error::Error;
6use serde_json::value::Value;
7use std::cmp::{Ordering, max};
8use std::collections::BTreeMap;
9use std::fmt;
10use std::iter::Iterator;
11use std::string::ToString;
12use std::vec;
13
14use crate::ToJmespath;
15use crate::ast::{Ast, Comparator};
16use crate::{JmespathError, Rcvar};
17use serde_json::Number;
18use std::convert::TryFrom;
19
20/// JMESPath types.
21#[derive(Debug, PartialEq, PartialOrd, Eq, Ord)]
22pub enum JmespathType {
23    Null,
24    String,
25    Number,
26    Boolean,
27    Array,
28    Object,
29    Expref,
30}
31
32impl fmt::Display for JmespathType {
33    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
34        write!(
35            fmt,
36            "{}",
37            match *self {
38                JmespathType::Null => "null",
39                JmespathType::String => "string",
40                JmespathType::Number => "number",
41                JmespathType::Boolean => "boolean",
42                JmespathType::Array => "array",
43                JmespathType::Object => "object",
44                JmespathType::Expref => "expref",
45            }
46        )
47    }
48}
49
50/// JMESPath variable.
51#[derive(Clone, Debug)]
52pub enum Variable {
53    Null,
54    String(String),
55    Bool(bool),
56    Number(Number),
57    Array(Vec<Rcvar>),
58    Object(BTreeMap<String, Rcvar>),
59    Expref(Ast),
60}
61
62impl Eq for Variable {}
63
64/// Compares two floats for equality.
65///
66/// Allows for equivalence of floating point numbers like
67/// 0.7100000000000002 and 0.71.
68///
69/// Based on http://stackoverflow.com/a/4915891
70fn float_eq(a: f64, b: f64) -> bool {
71    use std::f64;
72    let abs_a = a.abs();
73    let abs_b = b.abs();
74    let diff = (a - b).abs();
75    if a == b {
76        true
77    } else if !a.is_normal() || !b.is_normal() {
78        // a or b is zero or both are extremely close to it
79        // relative error is less meaningful here.
80        diff < (f64::EPSILON * f64::MIN_POSITIVE)
81    } else {
82        // use relative error.
83        diff / (abs_a + abs_b) < f64::EPSILON
84    }
85}
86
87/// Implement PartialEq for looser floating point comparisons.
88impl PartialEq for Variable {
89    fn eq(&self, other: &Variable) -> bool {
90        if self.get_type() != other.get_type() {
91            false
92        } else {
93            match self {
94                Variable::Number(a) => {
95                    if let (Some(a), Some(b)) = (a.as_f64(), other.as_number()) {
96                        float_eq(a, b)
97                    } else {
98                        false
99                    }
100                }
101                Variable::String(s) => Some(s) == other.as_string(),
102                Variable::Bool(b) => Some(*b) == other.as_boolean(),
103                Variable::Array(a) => Some(a) == other.as_array(),
104                Variable::Object(o) => Some(o) == other.as_object(),
105                Variable::Expref(e) => Some(e) == other.as_expref(),
106                Variable::Null => true,
107            }
108        }
109    }
110}
111
112/// Implement PartialOrd so that Ast can be in the PartialOrd of Variable.
113impl PartialOrd<Variable> for Variable {
114    fn partial_cmp(&self, other: &Variable) -> Option<Ordering> {
115        Some(self.cmp(other))
116    }
117
118    fn lt(&self, other: &Variable) -> bool {
119        self.cmp(other) == Ordering::Less
120    }
121
122    fn le(&self, other: &Variable) -> bool {
123        let ordering = self.cmp(other);
124        ordering == Ordering::Equal || ordering == Ordering::Less
125    }
126
127    fn gt(&self, other: &Variable) -> bool {
128        self.cmp(other) == Ordering::Greater
129    }
130
131    fn ge(&self, other: &Variable) -> bool {
132        let ordering = self.cmp(other);
133        ordering == Ordering::Equal || ordering == Ordering::Greater
134    }
135}
136
137impl Ord for Variable {
138    fn cmp(&self, other: &Self) -> Ordering {
139        let var_type = self.get_type();
140        // Variables of different types are considered equal.
141        if var_type != other.get_type() {
142            Ordering::Equal
143        } else {
144            match var_type {
145                JmespathType::String => {
146                    if let (Some(a), Some(b)) = (self.as_string(), other.as_string()) {
147                        a.cmp(b)
148                    } else {
149                        Ordering::Equal
150                    }
151                }
152                JmespathType::Number => {
153                    if let (Some(a), Some(b)) = (self.as_number(), other.as_number()) {
154                        a.partial_cmp(&b).unwrap_or(Ordering::Less)
155                    } else {
156                        Ordering::Equal
157                    }
158                }
159                _ => Ordering::Equal,
160            }
161        }
162    }
163}
164
165/// Write the JSON representation of a value, converting expref to a JSON
166/// string containing the debug dump of the expref variable.
167impl fmt::Display for Variable {
168    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
169        write!(
170            fmt,
171            "{}",
172            serde_json::to_string(self)
173                .unwrap_or_else(|err| format!("unable to stringify Variable. Err: {err}"))
174        )
175    }
176}
177
178/// Generic way of converting a Map in a Value to a Variable.
179fn convert_map<'a, T>(value: T) -> Result<Variable, JmespathError>
180where
181    T: Iterator<Item = (&'a String, &'a Value)>,
182{
183    let mut map: BTreeMap<String, Rcvar> = BTreeMap::new();
184    for kvp in value {
185        map.insert(kvp.0.to_owned(), kvp.1.to_jmespath()?);
186    }
187    Ok(Variable::Object(map))
188}
189
190/// Convert a borrowed Value to a Variable.
191impl<'a> TryFrom<&'a Value> for Variable {
192    type Error = JmespathError;
193
194    fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
195        let var = match *value {
196            Value::String(ref s) => Variable::String(s.to_owned()),
197            Value::Null => Variable::Null,
198            Value::Bool(b) => Variable::Bool(b),
199            Value::Number(ref n) => Variable::Number(n.clone()),
200            Value::Object(ref values) => convert_map(values.iter())?,
201            Value::Array(ref values) => Variable::Array(
202                values
203                    .iter()
204                    .map(|v| v.to_jmespath())
205                    .collect::<Result<_, JmespathError>>()?,
206            ),
207        };
208        Ok(var)
209    }
210}
211
212/// Slightly optimized method for converting from an owned Value.
213impl TryFrom<Value> for Variable {
214    type Error = JmespathError;
215
216    fn try_from(value: Value) -> Result<Self, Self::Error> {
217        let var = match value {
218            Value::String(s) => Variable::String(s),
219            Value::Null => Variable::Null,
220            Value::Bool(b) => Variable::Bool(b),
221            Value::Number(n) => Variable::Number(n),
222            Value::Object(ref values) => convert_map(values.iter())?,
223            Value::Array(mut values) => Variable::Array(
224                values
225                    .drain(..)
226                    .map(|v| v.to_jmespath())
227                    .collect::<Result<_, JmespathError>>()?,
228            ),
229        };
230        Ok(var)
231    }
232}
233
234impl Variable {
235    /// Shortcut function to encode a `T` into a JMESPath `Variable`
236    pub fn from_serializable<T>(value: T) -> Result<Variable, JmespathError>
237    where
238        T: ser::Serialize,
239    {
240        Ok(to_variable(value)?)
241    }
242
243    /// Create a JMESPath Variable from a JSON encoded string.
244    pub fn from_json(s: &str) -> Result<Self, String> {
245        serde_json::from_str::<Variable>(s).map_err(|e| e.to_string())
246    }
247
248    /// Returns true if the Variable is an Array. Returns false otherwise.
249    pub fn is_array(&self) -> bool {
250        self.as_array().is_some()
251    }
252
253    /// If the Variable value is an Array, returns the associated vector.
254    /// Returns None otherwise.
255    pub fn as_array(&self) -> Option<&Vec<Rcvar>> {
256        match self {
257            Variable::Array(array) => Some(array),
258            _ => None,
259        }
260    }
261
262    /// Returns true if the value is an Object.
263    pub fn is_object(&self) -> bool {
264        self.as_object().is_some()
265    }
266
267    /// If the value is an Object, returns the associated BTreeMap.
268    /// Returns None otherwise.
269    pub fn as_object(&self) -> Option<&BTreeMap<String, Rcvar>> {
270        match self {
271            Variable::Object(map) => Some(map),
272            _ => None,
273        }
274    }
275
276    /// Returns true if the value is a String. Returns false otherwise.
277    pub fn is_string(&self) -> bool {
278        self.as_string().is_some()
279    }
280
281    /// If the value is a String, returns the associated str.
282    /// Returns None otherwise.
283    pub fn as_string(&self) -> Option<&String> {
284        match self {
285            Variable::String(s) => Some(s),
286            _ => None,
287        }
288    }
289
290    /// Returns true if the value is a Number. Returns false otherwise.
291    pub fn is_number(&self) -> bool {
292        matches!(self, Variable::Number(_))
293    }
294
295    /// If the value is a number, return or cast it to a f64.
296    /// Returns None otherwise.
297    pub fn as_number(&self) -> Option<f64> {
298        match self {
299            Variable::Number(f) => f.as_f64(),
300            _ => None,
301        }
302    }
303
304    /// Returns true if the value is a Boolean. Returns false otherwise.
305    pub fn is_boolean(&self) -> bool {
306        self.as_boolean().is_some()
307    }
308
309    /// If the value is a Boolean, returns the associated bool.
310    /// Returns None otherwise.
311    pub fn as_boolean(&self) -> Option<bool> {
312        match self {
313            Variable::Bool(b) => Some(*b),
314            _ => None,
315        }
316    }
317
318    /// Returns true if the value is a Null. Returns false otherwise.
319    pub fn is_null(&self) -> bool {
320        self.as_null().is_some()
321    }
322
323    /// If the value is a Null, returns ().
324    /// Returns None otherwise.
325    pub fn as_null(&self) -> Option<()> {
326        match self {
327            Variable::Null => Some(()),
328            _ => None,
329        }
330    }
331
332    /// Returns true if the value is an expression reference.
333    /// Returns false otherwise.
334    pub fn is_expref(&self) -> bool {
335        self.as_expref().is_some()
336    }
337
338    /// If the value is an expression reference, returns the associated Ast node.
339    /// Returns None otherwise.
340    pub fn as_expref(&self) -> Option<&Ast> {
341        match *self {
342            Variable::Expref(ref ast) => Some(ast),
343            _ => None,
344        }
345    }
346
347    /// If the value is an object, returns the value associated with the provided key.
348    /// Otherwise, returns Null.
349    #[inline]
350    pub fn get_field(&self, key: &str) -> Rcvar {
351        if let Variable::Object(map) = self {
352            if let Some(result) = map.get(key) {
353                return result.clone();
354            }
355        }
356        Rcvar::new(Variable::Null)
357    }
358
359    /// If the value is an array, then gets an array value by index. Otherwise returns Null.
360    #[inline]
361    pub fn get_index(&self, index: usize) -> Rcvar {
362        if let Variable::Array(array) = self {
363            if let Some(result) = array.get(index) {
364                return result.clone();
365            }
366        }
367        Rcvar::new(Variable::Null)
368    }
369
370    /// Retrieves an index from the end of an array.
371    ///
372    /// Returns Null if not an array or if the index is not present.
373    /// The formula for determining the index position is length - index (i.e., an
374    /// index of 0 or 1 is treated as the end of the array).
375    pub fn get_negative_index(&self, index: usize) -> Rcvar {
376        if let Variable::Array(array) = self {
377            let adjusted_index = max(index, 1);
378            if array.len() >= adjusted_index {
379                return array[array.len() - adjusted_index].clone();
380            }
381        }
382        Rcvar::new(Variable::Null)
383    }
384
385    /// Returns true or false based on if the Variable value is considered truthy.
386    pub fn is_truthy(&self) -> bool {
387        match self {
388            Variable::Bool(b) => *b,
389            Variable::String(s) => !s.is_empty(),
390            Variable::Array(a) => !a.is_empty(),
391            Variable::Object(o) => !o.is_empty(),
392            Variable::Number(_) => true,
393            _ => false,
394        }
395    }
396
397    /// Returns the JMESPath type name of a Variable value.
398    pub fn get_type(&self) -> JmespathType {
399        match *self {
400            Variable::Bool(_) => JmespathType::Boolean,
401            Variable::String(_) => JmespathType::String,
402            Variable::Number(_) => JmespathType::Number,
403            Variable::Array(_) => JmespathType::Array,
404            Variable::Object(_) => JmespathType::Object,
405            Variable::Null => JmespathType::Null,
406            Variable::Expref(_) => JmespathType::Expref,
407        }
408    }
409
410    /// Compares two Variable values using a comparator.
411    pub fn compare(&self, cmp: &Comparator, value: &Variable) -> Option<bool> {
412        // Ordering requires numeric values.
413        if !(self.is_number() && value.is_number()
414            || *cmp == Comparator::NotEqual
415            || *cmp == Comparator::Equal)
416        {
417            return None;
418        }
419        match *cmp {
420            Comparator::Equal => Some(*self == *value),
421            Comparator::NotEqual => Some(*self != *value),
422            Comparator::LessThan => Some(*self < *value),
423            Comparator::LessThanEqual => Some(*self <= *value),
424            Comparator::GreaterThan => Some(*self > *value),
425            Comparator::GreaterThanEqual => Some(*self >= *value),
426        }
427    }
428
429    /// Returns a slice of the variable if the variable is an array.
430    pub fn slice(&self, start: Option<i32>, stop: Option<i32>, step: i32) -> Option<Vec<Rcvar>> {
431        self.as_array().map(|a| slice(a, start, stop, step))
432    }
433}
434
435impl Variable {
436    fn unexpected(&self) -> de::Unexpected<'_> {
437        match self {
438            Variable::Null => de::Unexpected::Unit,
439            Variable::Bool(b) => de::Unexpected::Bool(*b),
440            Variable::Number(_) => de::Unexpected::Other("number"),
441            Variable::String(s) => de::Unexpected::Str(s),
442            Variable::Array(_) => de::Unexpected::Seq,
443            Variable::Object(_) => de::Unexpected::Map,
444            Variable::Expref(_) => de::Unexpected::Other("expression"),
445        }
446    }
447}
448
449// ------------------------------------------
450// Variable slicing implementation
451// ------------------------------------------
452
453fn slice(array: &[Rcvar], start: Option<i32>, stop: Option<i32>, step: i32) -> Vec<Rcvar> {
454    let mut result = vec![];
455    let len = array.len() as i32;
456    if len == 0 {
457        return result;
458    }
459    let a: i32 = match start {
460        Some(starting_index) => adjust_slice_endpoint(len, starting_index, step),
461        _ if step < 0 => len - 1,
462        _ => 0,
463    };
464    let b: i32 = match stop {
465        Some(ending_index) => adjust_slice_endpoint(len, ending_index, step),
466        _ if step < 0 => -1,
467        _ => len,
468    };
469    let mut i = a;
470    if step > 0 {
471        while i < b {
472            result.push(array[i as usize].clone());
473            i += step;
474        }
475    } else {
476        while i > b {
477            result.push(array[i as usize].clone());
478            i += step;
479        }
480    }
481    result
482}
483
484#[inline]
485fn adjust_slice_endpoint(len: i32, mut endpoint: i32, step: i32) -> i32 {
486    if endpoint < 0 {
487        endpoint += len;
488        if endpoint >= 0 {
489            endpoint
490        } else if step < 0 {
491            -1
492        } else {
493            0
494        }
495    } else if endpoint < len {
496        endpoint
497    } else if step < 0 {
498        len - 1
499    } else {
500        len
501    }
502}
503
504// Serde Variable deserialization
505// ------------------------------------------
506// Below begins the amazingly complicated code needed to implement
507// serde serialization and deserialization for Variable. This code
508// is ported from the serde_json::Value implementation and adapted
509// for Variable and Rcvar. There are a few instances of
510// `(*self).clone` that I don't like, but I'm not sure how to work
511// around it.
512
513/// Shortcut function to encode a `T` into a JMESPath `Variable`
514fn to_variable<T>(value: T) -> Result<Variable, Error>
515where
516    T: ser::Serialize,
517{
518    value.serialize(Serializer)
519}
520
521/// Serde deserialization for Variable
522impl<'de> de::Deserialize<'de> for Variable {
523    #[inline]
524    fn deserialize<D>(deserializer: D) -> Result<Variable, D::Error>
525    where
526        D: de::Deserializer<'de>,
527    {
528        struct VariableVisitor;
529
530        impl<'de> de::Visitor<'de> for VariableVisitor {
531            type Value = Variable;
532
533            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
534                formatter.write_str("any valid JMESPath variable")
535            }
536
537            #[inline]
538            fn visit_bool<E>(self, value: bool) -> Result<Variable, E> {
539                Ok(Variable::Bool(value))
540            }
541
542            #[inline]
543            fn visit_i64<E>(self, value: i64) -> Result<Variable, E> {
544                Ok(Variable::Number(value.into()))
545            }
546
547            #[inline]
548            fn visit_u64<E>(self, value: u64) -> Result<Variable, E> {
549                Ok(Variable::Number(value.into()))
550            }
551
552            #[inline]
553            fn visit_f64<E>(self, value: f64) -> Result<Variable, E> {
554                Ok(Number::from_f64(value).map_or(Variable::Null, Variable::Number))
555            }
556
557            #[inline]
558            fn visit_str<E>(self, value: &str) -> Result<Variable, E>
559            where
560                E: de::Error,
561            {
562                self.visit_string(String::from(value))
563            }
564
565            #[inline]
566            fn visit_string<E>(self, value: String) -> Result<Variable, E> {
567                Ok(Variable::String(value))
568            }
569
570            #[inline]
571            fn visit_none<E>(self) -> Result<Variable, E> {
572                Ok(Variable::Null)
573            }
574
575            #[inline]
576            fn visit_some<D>(self, deserializer: D) -> Result<Variable, D::Error>
577            where
578                D: de::Deserializer<'de>,
579            {
580                de::Deserialize::deserialize(deserializer)
581            }
582
583            #[inline]
584            fn visit_unit<E>(self) -> Result<Variable, E> {
585                Ok(Variable::Null)
586            }
587
588            #[inline]
589            fn visit_seq<V>(self, mut visitor: V) -> Result<Variable, V::Error>
590            where
591                V: de::SeqAccess<'de>,
592            {
593                let mut values = vec![];
594
595                while let Some(elem) = visitor.next_element()? {
596                    values.push(elem);
597                }
598
599                Ok(Variable::Array(values))
600            }
601
602            #[inline]
603            fn visit_map<V>(self, mut visitor: V) -> Result<Variable, V::Error>
604            where
605                V: de::MapAccess<'de>,
606            {
607                let mut values = BTreeMap::new();
608
609                while let Some((key, value)) = visitor.next_entry()? {
610                    values.insert(key, value);
611                }
612
613                Ok(Variable::Object(values))
614            }
615        }
616
617        deserializer.deserialize_any(VariableVisitor)
618    }
619}
620
621impl<'de> de::Deserializer<'de> for Variable {
622    type Error = Error;
623
624    #[inline]
625    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
626    where
627        V: de::Visitor<'de>,
628    {
629        match self {
630            Variable::Null => visitor.visit_unit(),
631            Variable::Bool(v) => visitor.visit_bool(v),
632            Variable::Number(v) => v.deserialize_any(visitor),
633            Variable::String(v) => visitor.visit_string(v),
634            Variable::Array(v) => {
635                let len = v.len();
636                visitor.visit_seq(SeqDeserializer {
637                    iter: v.into_iter(),
638                    len,
639                })
640            }
641            Variable::Object(v) => visitor.visit_map(MapDeserializer {
642                iter: v.into_iter(),
643                value: None,
644            }),
645            Variable::Expref(v) => visitor.visit_string(format!("<expression: {v:?}>")),
646        }
647    }
648
649    #[inline]
650    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
651    where
652        V: de::Visitor<'de>,
653    {
654        match self {
655            Variable::Null => visitor.visit_none(),
656            _ => visitor.visit_some(self),
657        }
658    }
659
660    #[inline]
661    fn deserialize_enum<V>(
662        self,
663        _name: &str,
664        _variants: &'static [&'static str],
665        visitor: V,
666    ) -> Result<V::Value, Error>
667    where
668        V: de::Visitor<'de>,
669    {
670        let (variant, value) = match self {
671            Variable::Object(value) => {
672                let mut iter = value.into_iter();
673                let (variant, value) = match iter.next() {
674                    Some(v) => v,
675                    None => {
676                        return Err(de::Error::invalid_value(
677                            de::Unexpected::Map,
678                            &"map with a single key",
679                        ));
680                    }
681                };
682                // enums are encoded in json as maps with a single key:value pair
683                if iter.next().is_some() {
684                    return Err(de::Error::invalid_value(
685                        de::Unexpected::Map,
686                        &"map with a single key",
687                    ));
688                }
689                (variant, Some((*value).clone()))
690            }
691            Variable::String(variant) => (variant, None),
692            other => {
693                return Err(de::Error::invalid_type(
694                    other.unexpected(),
695                    &"string or map",
696                ));
697            }
698        };
699
700        visitor.visit_enum(EnumDeserializer {
701            val: value,
702            variant,
703        })
704    }
705
706    #[inline]
707    fn deserialize_newtype_struct<V>(
708        self,
709        _name: &'static str,
710        visitor: V,
711    ) -> Result<V::Value, Self::Error>
712    where
713        V: de::Visitor<'de>,
714    {
715        visitor.visit_newtype_struct(self)
716    }
717
718    forward_to_deserialize_any! {
719        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string
720        unit seq bytes byte_buf map unit_struct tuple_struct struct
721        identifier tuple ignored_any
722    }
723}
724
725struct VariantDeserializer {
726    val: Option<Variable>,
727}
728
729impl<'de> de::VariantAccess<'de> for VariantDeserializer {
730    type Error = Error;
731
732    fn unit_variant(self) -> Result<(), Error> {
733        match self.val {
734            Some(value) => de::Deserialize::deserialize(value),
735            None => Ok(()),
736        }
737    }
738
739    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
740    where
741        T: de::DeserializeSeed<'de>,
742    {
743        match self.val {
744            Some(value) => seed.deserialize(value),
745            None => Err(de::Error::invalid_type(
746                de::Unexpected::UnitVariant,
747                &"newtype variant",
748            )),
749        }
750    }
751
752    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
753    where
754        V: de::Visitor<'de>,
755    {
756        match self.val {
757            Some(Variable::Array(fields)) => de::Deserializer::deserialize_any(
758                SeqDeserializer {
759                    len: fields.len(),
760                    iter: fields.into_iter(),
761                },
762                visitor,
763            ),
764            Some(other) => Err(de::Error::invalid_type(
765                other.unexpected(),
766                &"tuple variant",
767            )),
768            None => Err(de::Error::invalid_type(
769                de::Unexpected::UnitVariant,
770                &"tuple variant",
771            )),
772        }
773    }
774
775    fn struct_variant<V>(
776        self,
777        _fields: &'static [&'static str],
778        visitor: V,
779    ) -> Result<V::Value, Error>
780    where
781        V: de::Visitor<'de>,
782    {
783        match self.val {
784            Some(Variable::Object(fields)) => de::Deserializer::deserialize_any(
785                MapDeserializer {
786                    iter: fields.into_iter(),
787                    value: None,
788                },
789                visitor,
790            ),
791            Some(other) => Err(de::Error::invalid_type(
792                other.unexpected(),
793                &"struct variant",
794            )),
795            _ => Err(de::Error::invalid_type(
796                de::Unexpected::UnitVariant,
797                &"struct variant",
798            )),
799        }
800    }
801}
802
803struct EnumDeserializer {
804    variant: String,
805    val: Option<Variable>,
806}
807
808impl<'de> de::EnumAccess<'de> for EnumDeserializer {
809    type Error = Error;
810    type Variant = VariantDeserializer;
811
812    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error>
813    where
814        V: de::DeserializeSeed<'de>,
815    {
816        let variant = self.variant.into_deserializer();
817        let visitor = VariantDeserializer { val: self.val };
818        seed.deserialize(variant).map(|v| (v, visitor))
819    }
820}
821
822struct SeqDeserializer {
823    iter: vec::IntoIter<Rcvar>,
824    len: usize,
825}
826
827impl<'de> de::Deserializer<'de> for SeqDeserializer {
828    type Error = Error;
829
830    #[inline]
831    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
832    where
833        V: de::Visitor<'de>,
834    {
835        if self.len == 0 {
836            visitor.visit_unit()
837        } else {
838            visitor.visit_seq(self)
839        }
840    }
841
842    forward_to_deserialize_any! {
843        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string
844        unit option seq bytes byte_buf map unit_struct newtype_struct
845        tuple_struct struct identifier tuple enum ignored_any
846    }
847}
848
849impl<'de> de::SeqAccess<'de> for SeqDeserializer {
850    type Error = Error;
851
852    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
853    where
854        T: de::DeserializeSeed<'de>,
855    {
856        match self.iter.next() {
857            Some(value) => seed.deserialize(Variable::clone(&value)).map(Some),
858            None => Ok(None),
859        }
860    }
861
862    fn size_hint(&self) -> Option<usize> {
863        match self.iter.size_hint() {
864            (lower, Some(upper)) if lower == upper => Some(upper),
865            _ => None,
866        }
867    }
868}
869
870struct MapDeserializer {
871    iter: <BTreeMap<String, Rcvar> as IntoIterator>::IntoIter,
872    value: Option<Variable>,
873}
874
875impl<'de> de::MapAccess<'de> for MapDeserializer {
876    type Error = Error;
877
878    fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
879    where
880        T: de::DeserializeSeed<'de>,
881    {
882        match self.iter.next() {
883            Some((key, value)) => {
884                self.value = Some(Variable::clone(&value));
885                seed.deserialize(Variable::String(key)).map(Some)
886            }
887            None => Ok(None),
888        }
889    }
890
891    fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Error>
892    where
893        T: de::DeserializeSeed<'de>,
894    {
895        match self.value.take() {
896            Some(value) => seed.deserialize(value),
897            None => Err(de::Error::custom("value is missing")),
898        }
899    }
900
901    fn size_hint(&self) -> Option<usize> {
902        match self.iter.size_hint() {
903            (lower, Some(upper)) if lower == upper => Some(upper),
904            _ => None,
905        }
906    }
907}
908
909impl<'de> de::Deserializer<'de> for MapDeserializer {
910    type Error = Error;
911
912    #[inline]
913    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
914    where
915        V: de::Visitor<'de>,
916    {
917        visitor.visit_map(self)
918    }
919
920    forward_to_deserialize_any! {
921        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string
922        unit option seq bytes byte_buf map unit_struct newtype_struct
923        tuple_struct struct identifier tuple enum ignored_any
924    }
925}
926
927// Serde Variable serialization
928impl ser::Serialize for Variable {
929    #[inline]
930    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
931    where
932        S: ser::Serializer,
933    {
934        match self {
935            Variable::Null => serializer.serialize_unit(),
936            Variable::Bool(v) => serializer.serialize_bool(*v),
937            Variable::Number(v) => v.serialize(serializer),
938            Variable::String(v) => serializer.serialize_str(v),
939            Variable::Array(v) => v.serialize(serializer),
940            Variable::Object(v) => v.serialize(serializer),
941            Variable::Expref(e) => serializer.serialize_str(&format!("<expression: {e:?}>")),
942        }
943    }
944}
945
946/// Create a `serde::Serializer` that serializes a `Serialize`e into a `Variable`.
947#[derive(Debug, Default)]
948pub struct Serializer;
949
950#[doc(hidden)]
951pub struct SeqState(Vec<Rcvar>);
952
953#[doc(hidden)]
954pub struct TupleVariantState {
955    name: String,
956    vec: Vec<Rcvar>,
957}
958
959#[doc(hidden)]
960pub struct StructVariantState {
961    name: String,
962    map: BTreeMap<String, Rcvar>,
963}
964
965#[doc(hidden)]
966pub struct MapState {
967    map: BTreeMap<String, Rcvar>,
968    next_key: Option<String>,
969}
970
971impl ser::Serializer for Serializer {
972    type Ok = Variable;
973    type Error = Error;
974
975    type SerializeSeq = SeqState;
976    type SerializeTuple = SeqState;
977    type SerializeTupleStruct = SeqState;
978    type SerializeTupleVariant = TupleVariantState;
979    type SerializeMap = MapState;
980    type SerializeStruct = MapState;
981    type SerializeStructVariant = StructVariantState;
982
983    #[inline]
984    fn serialize_bool(self, value: bool) -> Result<Variable, Error> {
985        Ok(Variable::Bool(value))
986    }
987
988    #[inline]
989    fn serialize_i8(self, value: i8) -> Result<Variable, Error> {
990        Ok(Variable::Number(Number::from(value)))
991    }
992
993    #[inline]
994    fn serialize_i16(self, value: i16) -> Result<Variable, Error> {
995        Ok(Variable::Number(Number::from(value)))
996    }
997
998    #[inline]
999    fn serialize_i32(self, value: i32) -> Result<Variable, Error> {
1000        Ok(Variable::Number(Number::from(value)))
1001    }
1002
1003    fn serialize_i64(self, value: i64) -> Result<Variable, Error> {
1004        Ok(Variable::Number(Number::from(value)))
1005    }
1006
1007    #[inline]
1008    fn serialize_u8(self, value: u8) -> Result<Variable, Error> {
1009        Ok(Variable::Number(Number::from(value)))
1010    }
1011
1012    #[inline]
1013    fn serialize_u16(self, value: u16) -> Result<Variable, Error> {
1014        Ok(Variable::Number(Number::from(value)))
1015    }
1016
1017    #[inline]
1018    fn serialize_u32(self, value: u32) -> Result<Variable, Error> {
1019        Ok(Variable::Number(Number::from(value)))
1020    }
1021
1022    #[inline]
1023    fn serialize_u64(self, value: u64) -> Result<Variable, Error> {
1024        Ok(Variable::Number(Number::from(value)))
1025    }
1026
1027    #[inline]
1028    fn serialize_f32(self, value: f32) -> Result<Variable, Error> {
1029        self.serialize_f64(value as f64)
1030    }
1031
1032    #[inline]
1033    fn serialize_f64(self, value: f64) -> Result<Variable, Error> {
1034        Ok(Number::from_f64(value).map_or(Variable::Null, Variable::Number))
1035    }
1036
1037    #[inline]
1038    fn serialize_char(self, value: char) -> Result<Variable, Error> {
1039        let mut s = String::new();
1040        s.push(value);
1041        self.serialize_str(&s)
1042    }
1043
1044    #[inline]
1045    fn serialize_str(self, value: &str) -> Result<Variable, Error> {
1046        Ok(Variable::String(String::from(value)))
1047    }
1048
1049    fn serialize_bytes(self, value: &[u8]) -> Result<Variable, Error> {
1050        let vec = value
1051            .iter()
1052            .map(|&b| Rcvar::new(Variable::Number(Number::from(b))))
1053            .collect();
1054        Ok(Variable::Array(vec))
1055    }
1056
1057    #[inline]
1058    fn serialize_unit(self) -> Result<Variable, Error> {
1059        Ok(Variable::Null)
1060    }
1061
1062    #[inline]
1063    fn serialize_unit_struct(self, _name: &'static str) -> Result<Variable, Error> {
1064        self.serialize_unit()
1065    }
1066
1067    #[inline]
1068    fn serialize_unit_variant(
1069        self,
1070        _name: &'static str,
1071        _variant_index: u32,
1072        variant: &'static str,
1073    ) -> Result<Variable, Error> {
1074        self.serialize_str(variant)
1075    }
1076
1077    #[inline]
1078    fn serialize_newtype_struct<T: ser::Serialize + ?Sized>(
1079        self,
1080        _name: &'static str,
1081        value: &T,
1082    ) -> Result<Variable, Error> {
1083        value.serialize(self)
1084    }
1085
1086    fn serialize_newtype_variant<T: ser::Serialize + ?Sized>(
1087        self,
1088        _name: &'static str,
1089        _variant_index: u32,
1090        variant: &'static str,
1091        value: &T,
1092    ) -> Result<Variable, Error> {
1093        let mut values = BTreeMap::new();
1094        values.insert(String::from(variant), Rcvar::new(to_variable(value)?));
1095        Ok(Variable::Object(values))
1096    }
1097
1098    #[inline]
1099    fn serialize_none(self) -> Result<Variable, Error> {
1100        self.serialize_unit()
1101    }
1102
1103    #[inline]
1104    fn serialize_some<V: ser::Serialize + ?Sized>(self, value: &V) -> Result<Variable, Error> {
1105        value.serialize(self)
1106    }
1107
1108    fn serialize_seq(self, len: Option<usize>) -> Result<SeqState, Error> {
1109        Ok(SeqState(Vec::with_capacity(len.unwrap_or(0))))
1110    }
1111
1112    fn serialize_tuple(self, len: usize) -> Result<SeqState, Error> {
1113        self.serialize_seq(Some(len))
1114    }
1115
1116    fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SeqState, Error> {
1117        self.serialize_seq(Some(len))
1118    }
1119
1120    fn serialize_tuple_variant(
1121        self,
1122        _name: &'static str,
1123        _variant_index: u32,
1124        variant: &'static str,
1125        len: usize,
1126    ) -> Result<TupleVariantState, Error> {
1127        Ok(TupleVariantState {
1128            name: String::from(variant),
1129            vec: Vec::with_capacity(len),
1130        })
1131    }
1132
1133    fn serialize_map(self, _len: Option<usize>) -> Result<MapState, Error> {
1134        Ok(MapState {
1135            map: BTreeMap::new(),
1136            next_key: None,
1137        })
1138    }
1139
1140    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<MapState, Error> {
1141        self.serialize_map(Some(len))
1142    }
1143
1144    fn serialize_struct_variant(
1145        self,
1146        _name: &'static str,
1147        _variant_index: u32,
1148        variant: &'static str,
1149        _len: usize,
1150    ) -> Result<StructVariantState, Error> {
1151        Ok(StructVariantState {
1152            name: String::from(variant),
1153            map: BTreeMap::new(),
1154        })
1155    }
1156}
1157
1158impl ser::SerializeSeq for SeqState {
1159    type Ok = Variable;
1160    type Error = Error;
1161
1162    fn serialize_element<T: ser::Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
1163        self.0.push(Rcvar::new(to_variable(value)?));
1164        Ok(())
1165    }
1166
1167    fn end(self) -> Result<Variable, Error> {
1168        Ok(Variable::Array(self.0))
1169    }
1170}
1171
1172impl ser::SerializeTuple for SeqState {
1173    type Ok = Variable;
1174    type Error = Error;
1175
1176    fn serialize_element<T: ser::Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
1177        ser::SerializeSeq::serialize_element(self, value)
1178    }
1179
1180    fn end(self) -> Result<Variable, Error> {
1181        ser::SerializeSeq::end(self)
1182    }
1183}
1184
1185impl ser::SerializeTupleStruct for SeqState {
1186    type Ok = Variable;
1187    type Error = Error;
1188
1189    fn serialize_field<T: ser::Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
1190        ser::SerializeSeq::serialize_element(self, value)
1191    }
1192
1193    fn end(self) -> Result<Variable, Error> {
1194        ser::SerializeSeq::end(self)
1195    }
1196}
1197
1198impl ser::SerializeTupleVariant for TupleVariantState {
1199    type Ok = Variable;
1200    type Error = Error;
1201
1202    fn serialize_field<T: ser::Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
1203        self.vec.push(Rcvar::new(to_variable(value)?));
1204        Ok(())
1205    }
1206
1207    fn end(self) -> Result<Variable, Error> {
1208        let mut object = BTreeMap::new();
1209        object.insert(self.name, Rcvar::new(Variable::Array(self.vec)));
1210        Ok(Variable::Object(object))
1211    }
1212}
1213
1214impl ser::SerializeMap for MapState {
1215    type Ok = Variable;
1216    type Error = Error;
1217
1218    fn serialize_key<T: ser::Serialize + ?Sized>(&mut self, key: &T) -> Result<(), Error> {
1219        match to_variable(key)? {
1220            Variable::String(s) => self.next_key = Some(s),
1221            _ => return Err(de::Error::custom("KeyMustBeAString")),
1222        };
1223        Ok(())
1224    }
1225
1226    fn serialize_value<T: ser::Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
1227        let key = self
1228            .next_key
1229            .take()
1230            .expect("serialize_value called before serialize_key");
1231        self.map.insert(key, Rcvar::new(to_variable(value)?));
1232        Ok(())
1233    }
1234
1235    fn end(self) -> Result<Variable, Error> {
1236        Ok(Variable::Object(self.map))
1237    }
1238}
1239
1240impl ser::SerializeStruct for MapState {
1241    type Ok = Variable;
1242    type Error = Error;
1243
1244    fn serialize_field<T: ser::Serialize + ?Sized>(
1245        &mut self,
1246        key: &'static str,
1247        value: &T,
1248    ) -> Result<(), Error> {
1249        ser::SerializeMap::serialize_key(self, key)?;
1250        ser::SerializeMap::serialize_value(self, value)
1251    }
1252
1253    fn end(self) -> Result<Variable, Error> {
1254        ser::SerializeMap::end(self)
1255    }
1256}
1257
1258impl ser::SerializeStructVariant for StructVariantState {
1259    type Ok = Variable;
1260    type Error = Error;
1261
1262    fn serialize_field<T: ser::Serialize + ?Sized>(
1263        &mut self,
1264        key: &'static str,
1265        value: &T,
1266    ) -> Result<(), Error> {
1267        self.map
1268            .insert(String::from(key), Rcvar::new(to_variable(value)?));
1269        Ok(())
1270    }
1271
1272    fn end(self) -> Result<Variable, Error> {
1273        let mut object = BTreeMap::new();
1274        object.insert(self.name, Rcvar::new(Variable::Object(self.map)));
1275        Ok(Variable::Object(object))
1276    }
1277}
1278
1279#[cfg(test)]
1280mod tests {
1281    use super::*;
1282    use crate::Rcvar;
1283    use crate::ast::{Ast, Comparator};
1284    use serde_json::{self, Number, Value};
1285    use std::collections::BTreeMap;
1286
1287    #[test]
1288    fn creates_variable_from_str() {
1289        assert_eq!(Ok(Variable::Bool(true)), Variable::from_json("true"));
1290        assert_eq!(
1291            Err("expected value at line 1 column 1".to_string()),
1292            Variable::from_json("abc")
1293        );
1294    }
1295
1296    #[test]
1297    fn test_determines_types() {
1298        assert_eq!(
1299            JmespathType::Object,
1300            Variable::from_json("{\"foo\": \"bar\"}")
1301                .unwrap()
1302                .get_type()
1303        );
1304        assert_eq!(
1305            JmespathType::Array,
1306            Variable::from_json("[\"foo\"]").unwrap().get_type()
1307        );
1308        assert_eq!(JmespathType::Null, Variable::Null.get_type());
1309        assert_eq!(JmespathType::Boolean, Variable::Bool(true).get_type());
1310        assert_eq!(
1311            JmespathType::String,
1312            Variable::String("foo".to_string()).get_type()
1313        );
1314        assert_eq!(
1315            JmespathType::Number,
1316            Variable::Number(Number::from_f64(1.0).unwrap()).get_type()
1317        );
1318    }
1319
1320    #[test]
1321    fn test_is_truthy() {
1322        assert!(
1323            Variable::from_json("{\"foo\": \"bar\"}")
1324                .unwrap()
1325                .is_truthy()
1326        );
1327        assert!(!Variable::from_json("{}").unwrap().is_truthy());
1328        assert!(Variable::from_json("[\"foo\"]").unwrap().is_truthy());
1329        assert!(!Variable::from_json("[]").unwrap().is_truthy());
1330        assert!(!Variable::Null.is_truthy());
1331        assert!(Variable::Bool(true).is_truthy());
1332        assert!(!Variable::Bool(false).is_truthy());
1333        assert!(Variable::String("foo".to_string()).is_truthy());
1334        assert!(!Variable::String("".to_string()).is_truthy());
1335        assert!(Variable::Number(Number::from_f64(10.0).unwrap()).is_truthy());
1336        assert!(Variable::Number(Number::from_f64(0.0).unwrap()).is_truthy());
1337    }
1338
1339    #[test]
1340    fn test_eq_ne_compare() {
1341        let l = Variable::String("foo".to_string());
1342        let r = Variable::String("foo".to_string());
1343        assert_eq!(Some(true), l.compare(&Comparator::Equal, &r));
1344        assert_eq!(Some(false), l.compare(&Comparator::NotEqual, &r));
1345    }
1346
1347    #[test]
1348    fn test_compare() {
1349        let invalid = Variable::String("foo".to_string());
1350        let l = Variable::Number(Number::from_f64(10.0).unwrap());
1351        let r = Variable::Number(Number::from_f64(20.0).unwrap());
1352        assert_eq!(None, invalid.compare(&Comparator::GreaterThan, &r));
1353        assert_eq!(Some(false), l.compare(&Comparator::GreaterThan, &r));
1354        assert_eq!(Some(false), l.compare(&Comparator::GreaterThanEqual, &r));
1355        assert_eq!(Some(true), r.compare(&Comparator::GreaterThan, &l));
1356        assert_eq!(Some(true), r.compare(&Comparator::GreaterThanEqual, &l));
1357        assert_eq!(Some(true), l.compare(&Comparator::LessThan, &r));
1358        assert_eq!(Some(true), l.compare(&Comparator::LessThanEqual, &r));
1359        assert_eq!(Some(false), r.compare(&Comparator::LessThan, &l));
1360        assert_eq!(Some(false), r.compare(&Comparator::LessThanEqual, &l));
1361    }
1362
1363    #[test]
1364    fn gets_value_from_object() {
1365        let var = Variable::from_json("{\"foo\":1}").unwrap();
1366        assert_eq!(
1367            Rcvar::new(Variable::Number(Number::from_f64(1.0).unwrap())),
1368            var.get_field("foo")
1369        );
1370    }
1371
1372    #[test]
1373    fn getting_value_from_non_object_is_null() {
1374        assert_eq!(
1375            Rcvar::new(Variable::Null),
1376            Variable::Bool(false).get_field("foo")
1377        );
1378    }
1379
1380    #[test]
1381    fn determines_if_null() {
1382        assert!(!Variable::Bool(true).is_null());
1383        assert!(Variable::Null.is_null());
1384    }
1385
1386    #[test]
1387    fn option_of_null() {
1388        assert_eq!(Some(()), Variable::Null.as_null());
1389        assert_eq!(None, Variable::Bool(true).as_null());
1390    }
1391
1392    #[test]
1393    fn determines_if_boolean() {
1394        assert!(Variable::Bool(true).is_boolean());
1395        assert!(!Variable::Null.is_boolean());
1396    }
1397
1398    #[test]
1399    fn option_of_boolean() {
1400        assert_eq!(Some(true), Variable::Bool(true).as_boolean());
1401        assert_eq!(None, Variable::Null.as_boolean());
1402    }
1403
1404    #[test]
1405    fn determines_if_string() {
1406        assert!(!Variable::Bool(true).is_string());
1407        assert!(Variable::String("foo".to_string()).is_string());
1408    }
1409
1410    #[test]
1411    fn option_of_string() {
1412        assert_eq!(
1413            Some(&"foo".to_string()),
1414            Variable::String("foo".to_string()).as_string()
1415        );
1416        assert_eq!(None, Variable::Null.as_string());
1417    }
1418
1419    #[test]
1420    fn test_is_number() {
1421        let value = Variable::from_json("12").unwrap();
1422        assert!(value.is_number());
1423    }
1424
1425    #[test]
1426    fn test_as_number() {
1427        let value = Variable::from_json("12.0").unwrap();
1428        assert_eq!(value.as_number(), Some(12f64));
1429    }
1430
1431    #[test]
1432    fn test_is_object() {
1433        let value = Variable::from_json("{}").unwrap();
1434        assert!(value.is_object());
1435    }
1436
1437    #[test]
1438    fn test_as_object() {
1439        let value = Variable::from_json("{}").unwrap();
1440        assert!(value.as_object().is_some());
1441    }
1442
1443    #[test]
1444    fn test_is_array() {
1445        let value = Variable::from_json("[1, 2, 3]").unwrap();
1446        assert!(value.is_array());
1447    }
1448
1449    #[test]
1450    fn test_as_array() {
1451        let value = Variable::from_json("[1, 2, 3]").unwrap();
1452        let array = value.as_array();
1453        let expected_length = 3;
1454        assert!(array.is_some() && array.unwrap().len() == expected_length);
1455    }
1456
1457    #[test]
1458    fn test_is_expref() {
1459        assert!(Variable::Expref(Ast::Identity { offset: 0 }).is_expref());
1460        assert_eq!(
1461            &Ast::Identity { offset: 0 },
1462            Variable::Expref(Ast::Identity { offset: 0 })
1463                .as_expref()
1464                .unwrap()
1465        );
1466    }
1467
1468    #[test]
1469    fn test_parses_json_scalar() {
1470        assert_eq!(Variable::Null, Variable::from_json("null").unwrap());
1471        assert_eq!(Variable::Bool(true), Variable::from_json("true").unwrap());
1472        assert_eq!(Variable::Bool(false), Variable::from_json("false").unwrap());
1473        assert_eq!(
1474            Variable::Number(Number::from(1)),
1475            Variable::from_json("1").unwrap()
1476        );
1477        assert_eq!(
1478            Variable::Number(Number::from_f64(-1.0).unwrap()),
1479            Variable::from_json("-1").unwrap()
1480        );
1481        assert_eq!(
1482            Variable::Number(Number::from_f64(1.5).unwrap()),
1483            Variable::from_json("1.5").unwrap()
1484        );
1485        assert_eq!(
1486            Variable::String("abc".to_string()),
1487            Variable::from_json("\"abc\"").unwrap()
1488        );
1489    }
1490
1491    #[test]
1492    fn test_parses_and_encodes_complex() {
1493        let js = "[null,true,1,[\"a\"],{\"b\":{\"c\":[[9.9],false]}},-1,1.0000001]";
1494        let var = Variable::from_json(js).unwrap();
1495        assert_eq!(js, var.to_string());
1496    }
1497
1498    #[test]
1499    fn test_parses_json_object() {
1500        let var = Variable::from_json("{\"a\": 1, \"b\": {\"c\": true}}").unwrap();
1501        let mut expected = BTreeMap::new();
1502        let mut sub_obj = BTreeMap::new();
1503        expected.insert(
1504            "a".to_string(),
1505            Rcvar::new(Variable::Number(Number::from_f64(1.0).unwrap())),
1506        );
1507        sub_obj.insert("c".to_string(), Rcvar::new(Variable::Bool(true)));
1508        expected.insert("b".to_string(), Rcvar::new(Variable::Object(sub_obj)));
1509        assert_eq!(var, Variable::Object(expected));
1510    }
1511
1512    #[test]
1513    fn test_converts_to_json() {
1514        let var = Variable::from_json("true").unwrap();
1515        let val = serde_json::to_value(&var).unwrap();
1516        assert_eq!(Value::Bool(true), val);
1517        let round_trip = serde_json::from_value::<Variable>(val).unwrap();
1518        assert_eq!(Variable::Bool(true), round_trip);
1519        // Try a more complex shape
1520        let var = Variable::from_json("[\"a\"]").unwrap();
1521        let val = serde_json::to_value(&var).unwrap();
1522        assert_eq!(Value::Array(vec![Value::String("a".to_string())]), val);
1523        let round_trip = serde_json::from_value::<Variable>(val).unwrap();
1524        assert_eq!(
1525            Variable::Array(vec![Rcvar::new(Variable::String("a".to_string()))]),
1526            round_trip
1527        );
1528    }
1529
1530    /// Converting an expression variable to a string is a special case.
1531    #[test]
1532    fn test_converts_to_string() {
1533        assert_eq!("true", Variable::Bool(true).to_string());
1534        assert_eq!("[true]", Variable::from_json("[true]").unwrap().to_string());
1535        let v = Variable::Expref(Ast::Identity { offset: 0 });
1536        assert_eq!("\"<expression: Identity { offset: 0 }>\"", v.to_string());
1537    }
1538
1539    #[test]
1540    fn test_compares_float_equality() {
1541        assert_eq!(
1542            Variable::Number(Number::from_f64(1.0).unwrap()),
1543            Variable::Number(Number::from_f64(1.0).unwrap())
1544        );
1545        assert_eq!(
1546            Variable::Number(Number::from_f64(0.0).unwrap()),
1547            Variable::Number(Number::from_f64(0.0).unwrap())
1548        );
1549        assert_ne!(
1550            Variable::Number(Number::from_f64(0.00001).unwrap()),
1551            Variable::Number(Number::from_f64(0.0).unwrap())
1552        );
1553        assert_eq!(
1554            Variable::Number(Number::from_f64(999.999).unwrap()),
1555            Variable::Number(Number::from_f64(999.999).unwrap())
1556        );
1557        assert_eq!(
1558            Variable::Number(Number::from_f64(1.000000000001).unwrap()),
1559            Variable::Number(Number::from_f64(1.000000000001).unwrap())
1560        );
1561        assert_eq!(
1562            Variable::Number(Number::from_f64(0.7100000000000002).unwrap()),
1563            Variable::Number(Number::from_f64(0.71).unwrap())
1564        );
1565        assert_eq!(
1566            Variable::Number(Number::from_f64(0.0000000000000002).unwrap()),
1567            Variable::Number(Number::from_f64(0.0000000000000002).unwrap())
1568        );
1569        assert_ne!(
1570            Variable::Number(Number::from_f64(0.0000000000000002).unwrap()),
1571            Variable::Number(Number::from_f64(0.0000000000000003).unwrap())
1572        );
1573    }
1574
1575    #[test]
1576    fn test_serialize_variable_with_positive_integer_value() {
1577        #[derive(serde_derive::Serialize)]
1578        struct Map {
1579            num: usize,
1580        }
1581
1582        let map = Map { num: 231 };
1583
1584        let var = Variable::from_serializable(&map).unwrap();
1585        let json_string = serde_json::to_string(&var).unwrap();
1586
1587        assert_eq!(r#"{"num":231}"#, json_string);
1588    }
1589
1590    #[test]
1591    fn test_serialize_variable_with_negative_integer_value() {
1592        #[derive(serde_derive::Serialize)]
1593        struct Map {
1594            num: isize,
1595        }
1596
1597        let map = Map { num: -2141 };
1598
1599        let var = Variable::from_serializable(&map).unwrap();
1600        let json_string = serde_json::to_string(&var).unwrap();
1601
1602        assert_eq!(r#"{"num":-2141}"#, json_string);
1603    }
1604
1605    #[test]
1606    fn test_serialize_variable_with_float_value() {
1607        #[derive(serde_derive::Serialize)]
1608        struct Map {
1609            num: f64,
1610        }
1611
1612        let map = Map { num: 41.0 };
1613
1614        let var = Variable::from_serializable(&map).unwrap();
1615        let json_string = serde_json::to_string(&var).unwrap();
1616
1617        assert_eq!(r#"{"num":41.0}"#, json_string);
1618    }
1619}