1use 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#[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#[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
64fn 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 diff < (f64::EPSILON * f64::MIN_POSITIVE)
81 } else {
82 diff / (abs_a + abs_b) < f64::EPSILON
84 }
85}
86
87impl 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
112impl 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 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
165impl 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
178fn 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
190impl<'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
212impl 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 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 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 pub fn is_array(&self) -> bool {
250 self.as_array().is_some()
251 }
252
253 pub fn as_array(&self) -> Option<&Vec<Rcvar>> {
256 match self {
257 Variable::Array(array) => Some(array),
258 _ => None,
259 }
260 }
261
262 pub fn is_object(&self) -> bool {
264 self.as_object().is_some()
265 }
266
267 pub fn as_object(&self) -> Option<&BTreeMap<String, Rcvar>> {
270 match self {
271 Variable::Object(map) => Some(map),
272 _ => None,
273 }
274 }
275
276 pub fn is_string(&self) -> bool {
278 self.as_string().is_some()
279 }
280
281 pub fn as_string(&self) -> Option<&String> {
284 match self {
285 Variable::String(s) => Some(s),
286 _ => None,
287 }
288 }
289
290 pub fn is_number(&self) -> bool {
292 matches!(self, Variable::Number(_))
293 }
294
295 pub fn as_number(&self) -> Option<f64> {
298 match self {
299 Variable::Number(f) => f.as_f64(),
300 _ => None,
301 }
302 }
303
304 pub fn is_boolean(&self) -> bool {
306 self.as_boolean().is_some()
307 }
308
309 pub fn as_boolean(&self) -> Option<bool> {
312 match self {
313 Variable::Bool(b) => Some(*b),
314 _ => None,
315 }
316 }
317
318 pub fn is_null(&self) -> bool {
320 self.as_null().is_some()
321 }
322
323 pub fn as_null(&self) -> Option<()> {
326 match self {
327 Variable::Null => Some(()),
328 _ => None,
329 }
330 }
331
332 pub fn is_expref(&self) -> bool {
335 self.as_expref().is_some()
336 }
337
338 pub fn as_expref(&self) -> Option<&Ast> {
341 match *self {
342 Variable::Expref(ref ast) => Some(ast),
343 _ => None,
344 }
345 }
346
347 #[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 #[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 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 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 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 pub fn compare(&self, cmp: &Comparator, value: &Variable) -> Option<bool> {
412 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 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
449fn 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
504fn to_variable<T>(value: T) -> Result<Variable, Error>
515where
516 T: ser::Serialize,
517{
518 value.serialize(Serializer)
519}
520
521impl<'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 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
927impl 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#[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 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 #[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}