teo_runtime/value/
value.rs

1use std::cmp::Ordering;
2use std::fmt::{Display, Formatter};
3use std::mem;
4use std::ops::{Add, Div, Mul, Sub, Rem, Neg, BitAnd, BitXor, BitOr, Not, Shl, Shr};
5use std::str::FromStr;
6use chrono::prelude::{DateTime, Utc};
7use indexmap::IndexMap;
8use bson::oid::ObjectId;
9use chrono::{NaiveDate, SecondsFormat};
10use regex::Regex;
11use bigdecimal::{BigDecimal, Zero};
12use itertools::Itertools;
13use teo_parser::r#type::synthesized_shape::SynthesizedShape;
14use teo_parser::r#type::Type;
15use super::file::File;
16use super::range::Range;
17use super::index::Index;
18use teo_result::{Error, Result};
19use crate::{model, r#struct};
20use crate::namespace::extensions::SynthesizedShapeReferenceExtension;
21use crate::namespace::Namespace;
22use crate::pipeline::Pipeline;
23use super::interface_enum_variant::InterfaceEnumVariant;
24use super::option_variant::OptionVariant;
25
26// Code from this file is inspired from serde json
27// https://github.com/serde-rs/json/blob/master/src/value/mod.rs
28
29/// Represents any valid Teon value.
30///
31#[derive(Debug, Clone)]
32pub enum Value {
33
34    /// Represents a Teon null value.
35    ///
36    /// ```
37    /// # use teo_runtime::teon;
38    /// #
39    /// let v = teon!(null);
40    /// ```
41    Null,
42
43    /// Represents a Teon Bool.
44    ///
45    /// ```
46    /// # use teo_runtime::teon;
47    /// #
48    /// let v = teon!(true);
49    /// ```
50    Bool(bool),
51
52    /// Represents a Teon Int.
53    ///
54    /// ```
55    /// # use teo_runtime::teon;
56    /// #
57    /// let v = teon!(12_i32);
58    /// ```
59    Int(i32),
60
61    /// Represents a Teon Int64.
62    ///
63    /// ```
64    /// # use teo_runtime::teon;
65    /// #
66    /// let v = teon!(12_i64);
67    /// ```
68    Int64(i64),
69
70    /// Represents a Teon Float32.
71    ///
72    /// ```
73    /// # use teo_runtime::teon;
74    /// #
75    /// let v = teon!(12.5_f32);
76    /// ```
77    Float32(f32),
78
79    /// Represents a Teon Float.
80    ///
81    /// ```
82    /// # use teo_runtime::teon;
83    /// #
84    /// let v = teon!(12.5_f64);
85    /// ```
86    Float(f64),
87
88    /// Represents a Teon Decimal.
89    ///
90    Decimal(BigDecimal),
91
92    /// Represents a Teon ObjectId.
93    ///
94    ObjectId(ObjectId),
95
96    /// Represents a Teon String.
97    ///
98    String(String),
99
100    /// Represents a Teon Date.
101    ///
102    Date(NaiveDate),
103
104    /// Represents a Teon DateTime.
105    ///
106    DateTime(DateTime<Utc>),
107
108    /// Represents a Teon Array.
109    ///
110    Array(Vec<Value>),
111
112    /// Represents a Teon btree_dictionary.
113    ///
114    Dictionary(IndexMap<String, Value>),
115
116    /// Represents a Teon Range.
117    ///
118    Range(Range),
119
120    /// Represents a Teon Tuple.
121    ///
122    Tuple(Vec<Value>),
123
124    /// Represents a Teon option variant.
125    ///
126    InterfaceEnumVariant(InterfaceEnumVariant),
127
128    /// Represents a Teon option variant.
129    ///
130    OptionVariant(OptionVariant),
131
132    /// Represents a Teon Regex.
133    ///
134    Regex(Regex),
135
136    /// Represents a Teon File.
137    ///
138    File(File),
139
140    /// Represents a model object.
141    ///
142    ModelObject(model::Object),
143
144    /// Represents a struct object.
145    ///
146    StructObject(r#struct::Object),
147
148    /// Represents a pipeline.
149    ///
150    Pipeline(Pipeline),
151
152    /// Represents a type as value.
153    ///
154    Type(Type),
155}
156
157impl Value {
158
159    // Access
160
161    pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
162        index.index_into(self)
163    }
164
165    pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
166        index.index_into_mut(self)
167    }
168
169    // Value
170
171    pub fn is_null(&self) -> bool {
172        match self {
173            Value::Null => true,
174            _ => false,
175        }
176    }
177
178    pub fn is_bool(&self) -> bool {
179        self.as_bool().is_some()
180    }
181
182    pub fn as_bool(&self) -> Option<bool> {
183        match *self {
184            Value::Bool(b) => Some(b),
185            _ => None,
186        }
187    }
188
189    pub fn is_int(&self) -> bool {
190        self.as_int().is_some()
191    }
192
193    pub fn as_int(&self) -> Option<i32> {
194        match *self {
195            Value::Int(v) => Some(v),
196            _ => None
197        }
198    }
199
200    pub fn to_int(&self) -> Option<i32> {
201        match *self {
202            Value::Int(i) => Some(i),
203            Value::Int64(i) => if i >= (i32::MAX as i64) {
204                None
205            } else {
206                Some(i as i32)
207            }
208            _ => None
209        }
210    }
211
212    pub fn is_int64(&self) -> bool {
213        self.as_int64().is_some()
214    }
215
216    pub fn as_int64(&self) -> Option<i64> {
217        match *self {
218            Value::Int64(v) => Some(v),
219            _ => None
220        }
221    }
222
223    pub fn to_int64(&self) -> Option<i64> {
224        match *self {
225            Value::Int64(v) => Some(v),
226            Value::Int(v) => Some(v as i64),
227            _ => None,
228        }
229    }
230
231    pub fn is_float32(&self) -> bool {
232        self.as_float32().is_some()
233    }
234
235    pub fn as_float32(&self) -> Option<f32> {
236        match *self {
237            Value::Float32(v) => Some(v),
238            _ => None
239        }
240    }
241
242    pub fn to_float32(&self) -> Option<f32> {
243        match *self {
244            Value::Float32(v) => Some(v),
245            Value::Float(v) => Some(v as f32),
246            Value::Int(i) => Some(i as f32),
247            Value::Int64(i) => Some(i as f32),
248            _ => None,
249        }
250    }
251
252    pub fn is_float(&self) -> bool {
253        self.as_float().is_some()
254    }
255
256    pub fn as_float(&self) -> Option<f64> {
257        match *self {
258            Value::Float(v) => Some(v),
259            _ => None
260        }
261    }
262
263    pub fn to_float(&self) -> Option<f64> {
264        match *self {
265            Value::Int(v) => Some(v as f64),
266            Value::Int64(v) => Some(v as f64),
267            Value::Float32(v) => Some(v as f64),
268            Value::Float(v) => Some(v),
269            _ => None
270        }
271    }
272
273    pub fn is_decimal(&self) -> bool {
274        match *self {
275            Value::Decimal(_) => true,
276            _ => false,
277        }
278    }
279
280    pub fn as_decimal(&self) -> Option<&BigDecimal> {
281        match self {
282            Value::Decimal(v) => Some(v),
283            _ => None
284        }
285    }
286
287    pub fn is_object_id(&self) -> bool {
288        self.as_object_id().is_some()
289    }
290
291    pub fn as_object_id(&self) -> Option<&ObjectId> {
292        match self {
293            Value::ObjectId(o) => Some(o),
294            _ => None,
295        }
296    }
297
298    pub fn is_string(&self) -> bool {
299        self.as_str().is_some()
300    }
301
302    pub fn as_str(&self) -> Option<&str> {
303        match self {
304            Value::String(s) => Some(s),
305            _ => None,
306        }
307    }
308
309    pub fn is_date(&self) -> bool {
310        self.as_date().is_some()
311    }
312
313    pub fn as_date(&self) -> Option<&NaiveDate> {
314        match self {
315            Value::Date(d) => Some(d),
316            _ => None,
317        }
318    }
319
320    pub fn is_datetime(&self) -> bool {
321        self.as_datetime().is_some()
322    }
323
324    pub fn as_datetime(&self) -> Option<&DateTime<Utc>> {
325        match self {
326            Value::DateTime(d) => Some(d),
327            _ => None,
328        }
329    }
330
331    pub fn is_array(&self) -> bool {
332        self.as_array().is_some()
333    }
334
335    pub fn as_array(&self) -> Option<&Vec<Value>> {
336        match self {
337            Value::Array(vec) => Some(vec),
338            _ => None,
339        }
340    }
341
342    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
343        match self {
344            Value::Array(vec) => Some(vec),
345            _ => None,
346        }
347    }
348
349    pub fn into_array(self) -> Option<Vec<Value>> {
350        match self {
351            Value::Array(vec) => Some(vec),
352            _ => None,
353        }
354    }
355
356    pub fn is_dictionary(&self) -> bool {
357        self.as_dictionary().is_some()
358    }
359
360    pub fn as_dictionary(&self) -> Option<&IndexMap<String, Value>> {
361        match self {
362            Value::Dictionary(map) => Some(map),
363            _ => None,
364        }
365    }
366
367    pub fn as_dictionary_mut(&mut self) -> Option<&mut IndexMap<String, Value>> {
368        match self {
369            Value::Dictionary(map) => Some(map),
370            _ => None,
371        }
372    }
373
374    pub fn is_range(&self) -> bool {
375        self.as_range().is_some()
376    }
377
378    pub fn as_range(&self) -> Option<&Range> {
379        match self {
380            Value::Range(r) => Some(r),
381            _ => None,
382        }
383    }
384
385    pub fn is_tuple(&self) -> bool {
386        self.as_range().is_some()
387    }
388
389    pub fn as_tuple(&self) -> Option<&Vec<Value>> {
390        match self {
391            Value::Tuple(t) => Some(t),
392            _ => None,
393        }
394    }
395
396    pub fn is_option_variant(&self) -> bool {
397        self.as_option_variant().is_some()
398    }
399
400    pub fn as_option_variant(&self) -> Option<&OptionVariant> {
401        match self {
402            Value::OptionVariant(e) => Some(e),
403            _ => None,
404        }
405    }
406
407    pub fn is_interface_enum_variant(&self) -> bool {
408        self.as_interface_enum_variant().is_some()
409    }
410
411    pub fn as_interface_enum_variant(&self) -> Option<&InterfaceEnumVariant> {
412        match self {
413            Value::InterfaceEnumVariant(e) => Some(e),
414            _ => None,
415        }
416    }
417
418    pub fn is_regexp(&self) -> bool {
419        self.as_regexp().is_some()
420    }
421
422    pub fn as_regexp(&self) -> Option<&Regex> {
423        match self {
424            Value::Regex(r) => Some(r),
425            _ => None,
426        }
427    }
428
429    pub fn is_file(&self) -> bool {
430        self.as_file().is_some()
431    }
432
433    pub fn as_file(&self) -> Option<&File> {
434        match self {
435            Value::File(f) => Some(f),
436            _ => None,
437        }
438    }
439
440    pub fn is_model_object(&self) -> bool {
441        self.as_model_object().is_some()
442    }
443
444    pub fn as_model_object(&self) -> Option<&model::Object> {
445        match self {
446            Value::ModelObject(v) => Some(v),
447            _ => None,
448        }
449    }
450
451    pub fn is_struct_object(&self) -> bool {
452        self.as_struct_object().is_some()
453    }
454
455    pub fn as_struct_object(&self) -> Option<&r#struct::Object> {
456        match self {
457            Value::StructObject(v) => Some(v),
458            _ => None,
459        }
460    }
461
462    pub fn is_pipeline(&self) -> bool {
463        self.as_pipeline().is_some()
464    }
465
466    pub fn as_pipeline(&self) -> Option<&Pipeline> {
467        match self {
468            Value::Pipeline(p) => Some(p),
469            _ => None,
470        }
471    }
472
473    pub fn is_type(&self) -> bool {
474        self.as_type().is_some()
475    }
476
477    pub fn as_type(&self) -> Option<&Type> {
478        match self {
479            Value::Type(p) => Some(p),
480            _ => None,
481        }
482    }
483
484    // Compound queries
485
486    pub fn is_any_int(&self) -> bool {
487        match *self {
488            Value::Int(_) | Value::Int64(_) => true,
489            _ => false,
490        }
491    }
492
493    pub fn is_any_float(&self) -> bool {
494        match *self {
495            Value::Float32(_) | Value::Float(_) => true,
496            _ => false,
497        }
498    }
499
500    pub fn is_any_int_or_float(&self) -> bool {
501        self.is_any_int() || self.is_any_float()
502    }
503
504    pub fn is_any_number(&self) -> bool {
505        self.is_any_int() || self.is_any_float() || self.is_decimal()
506    }
507
508    pub fn to_usize(&self) -> Option<usize> {
509        match *self {
510            Value::Int(n) => Some(n as usize),
511            Value::Int64(n) => Some(n as usize),
512            _ => None
513        }
514    }
515
516    pub fn wrap_into_vec<T>(self) -> Result<Vec<T>> where T: TryFrom<Value>, T::Error: Display {
517        match self {
518            Value::Array(array) => {
519                let mut retval = vec![];
520                for v in array {
521                    match T::try_from(v) {
522                        Ok(v) => retval.push(v),
523                        Err(e) => Err(Error::new(format!("{}", e)))?,
524                    }
525                }
526                Ok(retval)
527            },
528            _ => match T::try_from(self) {
529                Ok(v) => Ok(vec![v]),
530                Err(e) => Err(Error::new(format!("{}", e))),
531            }
532        }
533    }
534
535    /// Takes the value out of the `Value`, leaving a `Null` in its place.
536    ///
537    pub fn take(&mut self) -> Value {
538        mem::replace(self, Value::Null)
539    }
540
541    // Type hint
542
543    pub fn type_hint(&self) -> &str {
544        match self {
545            Value::Null => "Null",
546            Value::Bool(_) => "Bool",
547            Value::Int(_) => "Int",
548            Value::Int64(_) => "Int64",
549            Value::Float32(_) => "Float32",
550            Value::Float(_) => "Float",
551            Value::Decimal(_) => "Decimal",
552            Value::ObjectId(_) => "ObjectId",
553            Value::String(_) => "String",
554            Value::Date(_) => "Date",
555            Value::DateTime(_) => "DateTime",
556            Value::Array(_) => "Array",
557            Value::Dictionary(_) => "Dictionary",
558            Value::Range(_) => "Range",
559            Value::Tuple(_) => "Tuple",
560            Value::InterfaceEnumVariant(_) => "EnumVariant",
561            Value::OptionVariant(_) => "OptionVariant",
562            Value::Regex(_) => "RegExp",
563            Value::File(_) => "File",
564            Value::ModelObject(_) => "ModelObject",
565            Value::StructObject(_) => "StructObject",
566            Value::Pipeline(_) => "Pipeline",
567            Value::Type(_) => "Type",
568        }
569    }
570
571    pub fn recip(&self) -> Result<Value> {
572        Ok(match self {
573            Value::Int(n) => Value::Float((*n as f64).recip()),
574            Value::Int64(n) => Value::Float((*n as f64).recip()),
575            Value::Float32(n) => Value::Float32((*n).recip()),
576            Value::Float(n) => Value::Float((*n).recip()),
577            Value::Decimal(n) => Value::Decimal(BigDecimal::from_str("1").unwrap() / n),
578            _ => Err(Error::new("recip: value is not number"))?
579        })
580    }
581
582    pub fn normal_not(&self) -> Value {
583        Value::Bool(match self {
584            Value::Null => true,
585            Value::Bool(b) => !b,
586            Value::Int(i) => i.is_zero(),
587            Value::Int64(i) => i.is_zero(),
588            Value::Float32(f) => f.is_zero(),
589            Value::Float(f) => f.is_zero(),
590            Value::Decimal(d) => d.is_zero(),
591            Value::ObjectId(_) => false,
592            Value::String(s) => s.is_empty(),
593            Value::Date(_) => false,
594            Value::DateTime(_) => false,
595            Value::Array(a) => a.is_empty(),
596            Value::Dictionary(d) => d.is_empty(),
597            Value::Range(_) => false,
598            Value::Tuple(_) => false,
599            Value::InterfaceEnumVariant(e) => e.normal_not(),
600            Value::OptionVariant(o) => o.normal_not(),
601            Value::Regex(_) => false,
602            Value::File(_) => false,
603            Value::Pipeline(_) => false,
604            Value::ModelObject(_) => false,
605            Value::StructObject(_) => false,
606            Value::Type(_) => false,
607        })
608    }
609
610    pub fn and<'a>(&'a self, rhs: &'a Value) -> &'a Value {
611        if self.normal_not().is_false() {
612            rhs
613        } else {
614            self
615        }
616    }
617
618    pub fn or<'a>(&'a self, rhs: &'a Value) -> &'a Value {
619        if self.normal_not().is_false() {
620            self
621        } else {
622            rhs
623        }
624    }
625
626    pub fn is_false(&self) -> bool {
627        self.is_bool() && self.as_bool().unwrap() == false
628    }
629
630    pub fn is_true(&self) -> bool {
631        self.is_bool() && self.as_bool().unwrap() == true
632    }
633
634    pub fn try_into_err_prefix<T, E>(self, prefix: impl AsRef<str>) -> Result<T> where Error: From<E>, T: TryFrom<Value, Error = E> {
635        let result: std::result::Result<T, E> = self.try_into();
636        match result {
637            Ok(t) => Ok(t),
638            Err(e) => Err(Error::new(format!("{}: {}", prefix.as_ref(), Error::from(e)))),
639        }
640    }
641
642    fn try_into_err_message_inner<T, E>(self) -> Result<T> where Error: From<E>, T: TryFrom<Value, Error = E> {
643        Ok(self.try_into()?)
644    }
645
646    pub fn try_into_err_message<T, E>(self, message: impl AsRef<str>) -> Result<T> where Error: From<E>, T: TryFrom<Value, Error = E> {
647        let result: Result<T> = self.try_into_err_message_inner();
648        match result {
649            Ok(t) => Ok(t),
650            Err(_) => Err(Error::new(message.as_ref())),
651        }
652    }
653
654    pub fn try_ref_into_err_prefix<'a, T: 'a, E>(&'a self, prefix: impl AsRef<str>) -> Result<T> where Error: From<E>, T: TryFrom<&'a Value, Error = E> {
655        let result: std::result::Result<T, E> = self.try_into();
656        match result {
657            Ok(t) => Ok(t),
658            Err(e) => Err(Error::new(format!("{}: {}", prefix.as_ref(), Error::from(e)))),
659        }
660    }
661
662    pub fn try_ref_into_err_message<'a, T: 'a, E>(&'a self, message: impl AsRef<str>) -> Result<T> where Error: From<E>, T: TryFrom<&'a Value, Error = E> {
663        let result: std::result::Result<T, E> = self.try_into();
664        match result {
665            Ok(t) => Ok(t),
666            Err(_) => Err(Error::new(message.as_ref())),
667        }
668    }
669
670    pub(crate) fn cast(&self, target: Option<&Type>, namespace: &Namespace) -> Self {
671        if let Some(target) = target {
672            do_cast(self, target, namespace)
673        } else {
674            self.clone()
675        }
676    }
677
678    pub(crate) fn default_struct_path(&self) -> Result<Vec<&'static str>> {
679        Ok(match self {
680            Value::Null => vec!["std", "Null"],
681            Value::Bool(_) => vec!["std", "Bool"],
682            Value::Int(_) => vec!["std", "Int"],
683            Value::Int64(_) => vec!["std", "Int64"],
684            Value::Float32(_) => vec!["std", "Float32"],
685            Value::Float(_) => vec!["std", "Float"],
686            Value::Decimal(_) => vec!["std", "Decimal"],
687            Value::ObjectId(_) => vec!["std", "ObjectId"],
688            Value::String(_) => vec!["std", "String"],
689            Value::Date(_) => vec!["std", "Date"],
690            Value::DateTime(_) => vec!["std", "DateTime"],
691            Value::Array(_) => vec!["std", "Array"],
692            Value::Dictionary(_) => vec!["std", "Dictionary"],
693            Value::Range(_) => vec!["std", "Range"],
694            Value::Tuple(_) => Err(Error::new("tuple struct is not supported"))?,
695            Value::Regex(_) => vec!["std", "Regex"],
696            Value::File(_) => vec!["std", "File"],
697            Value::OptionVariant(_) => Err(Error::new("option variant struct is not supported"))?,
698            _ => Err(Error::new("primitive struct is not supported for this type"))?,
699        })
700    }
701
702    pub fn is_of_type(&self, t: &Type, namespace: &Namespace) -> bool {
703        match t {
704            Type::Undetermined => false,
705            Type::Ignored => true,
706            Type::Any => true,
707            Type::Union(types) => types.iter().any(|t| self.is_of_type(t, namespace)),
708            Type::Enumerable(inner) => if let Some(array) = self.as_array() {
709                array.iter().all(|v| v.is_of_type(inner, namespace))
710            } else {
711                self.is_of_type(inner, namespace)
712            },
713            Type::Optional(inner) => self.is_null() || self.is_of_type(inner, namespace),
714            Type::FieldType(_, _) => false,
715            Type::FieldName(_) => false,
716            Type::ShapeField(_) => false,
717            Type::GenericItem(_) => false,
718            Type::Keyword(_) => false,
719            Type::Type => self.is_type(),
720            Type::TypeValueAsType(_) => false,
721            Type::Null => self.is_null(),
722            Type::Bool => self.is_bool(),
723            Type::Int => self.is_int(),
724            Type::Int64 => self.is_int64(),
725            Type::Float32 => self.is_float32(),
726            Type::Float => self.is_float(),
727            Type::Decimal => self.is_decimal(),
728            Type::String => self.is_string(),
729            Type::ObjectId => self.is_object_id(),
730            Type::Date => self.is_date(),
731            Type::DateTime => self.is_datetime(),
732            Type::File => self.is_file(),
733            Type::Regex => self.is_regexp(),
734            Type::Array(inner) => if let Some(array) = self.as_array() {
735                array.iter().all(|v| v.is_of_type(inner, namespace))
736            } else {
737                false
738            },
739            Type::Dictionary(inner) => if let Some(dictionary) = self.as_dictionary() {
740                dictionary.values().all(|v| v.is_of_type(inner, namespace))
741            } else {
742                false
743            },
744            Type::Tuple(types) => if let Some(tuple) = self.as_tuple() {
745                types.len() == tuple.len() && tuple.iter().zip(types).all(|(a, b)| a.is_of_type(b, namespace))
746            } else {
747                false
748            },
749            Type::Range(inner) => if let Some(range) = self.as_range() {
750                range.start.is_of_type(inner, namespace) && range.end.is_of_type(inner, namespace)
751            } else {
752                false
753            }
754            Type::SynthesizedShape(_) => false, // todo
755            Type::SynthesizedShapeReference(_) => false, // todo
756            Type::DeclaredSynthesizedShape(_, _) => false, // todo
757            Type::EnumVariant(r) => false, // todo
758            Type::SynthesizedEnum(_) => false, // todo
759            Type::SynthesizedEnumReference(_) => false, // todo
760            Type::SynthesizedInterfaceEnum(_) => false, // todo
761            Type::SynthesizedInterfaceEnumReference(_) => false, // todo
762            Type::Shape => false,
763            Type::Model => false,
764            Type::ModelObject(r) => if let Some(object) = self.as_model_object() {
765                object.model().path() == r.string_path()
766            } else {
767                false
768            },
769            Type::InterfaceObject(_, _) => false, // todo
770            Type::StructObject(_, _) => false, // todo
771            Type::Middleware => false, // todo
772            Type::DataSet => false, // todo
773            Type::DataSetObject(_) => false, // todo
774            Type::DataSetGroup(_) => false, // todo
775            Type::DataSetRecord(_, _) => false, // todo
776            Type::Pipeline(_, _) => false, // todo
777        }
778    }
779
780}
781
782impl Default for Value {
783    fn default() -> Value {
784        Value::Null
785    }
786}
787
788fn check_enum_operands(name: &str, lhs: &Value, rhs: &Value) -> Result<()> {
789    if let (Some(_), Some(_)) = (lhs.as_option_variant(), rhs.as_option_variant()) {
790        Ok(())
791    } else {
792        Err(operands_error_message(lhs, rhs, name))
793    }
794}
795
796fn operand_error_message(operand: &Value, name: &str) -> Error {
797    Error::new(format!("cannot {name} {}", operand.type_hint()))
798}
799
800fn check_operands<F>(lhs: &Value, rhs: &Value, name: &str, matcher: F) -> Result<()> where F: Fn(&Value) -> bool {
801    let matcher_wrapper = |value: &Value| {
802        (&matcher)(value)
803    };
804    if !matcher_wrapper(lhs) || !matcher_wrapper(rhs) {
805        return Err(operands_error_message(lhs, rhs, name));
806    }
807    Ok(())
808}
809
810fn operands_error_message(lhs: &Value, rhs: &Value, name: &str) -> Error {
811    Error::new(format!("cannot {name} {} with {}", lhs.type_hint(), rhs.type_hint()))
812}
813
814impl Add for &Value {
815
816    type Output = Result<Value>;
817
818    fn add(self, rhs: Self) -> Self::Output {
819        Ok(match self {
820            Value::Int(v) => {
821                check_operands(&self, &rhs, "add", |v| v.is_any_int())?;
822                Value::Int(v + rhs.to_int().unwrap())
823            },
824            Value::Int64(v) => {
825                check_operands(&self, &rhs, "add", |v| v.is_any_int())?;
826                Value::Int64(v + rhs.to_int64().unwrap())
827            },
828            Value::Float32(v) => {
829                check_operands(&self, &rhs, "add", |v| v.is_any_int_or_float())?;
830                Value::Float32(v + rhs.to_float32().unwrap())
831            },
832            Value::Float(v) => {
833                check_operands(&self, &rhs, "add", |v| v.is_any_int_or_float())?;
834                Value::Float(v + rhs.to_float().unwrap())
835            },
836            Value::Decimal(d) => {
837                check_operands(&self, &rhs, "add", |v| v.is_decimal())?;
838                Value::Decimal(d + rhs.as_decimal().unwrap())
839            },
840            Value::String(s) => {
841                check_operands(&self, &rhs, "add", |v| v.is_string())?;
842                Value::String(s.to_owned() + rhs.as_str().unwrap())
843            }
844            _ => Err(operands_error_message(self, rhs, "add"))?,
845        })
846    }
847}
848
849impl Sub for &Value {
850
851    type Output = Result<Value>;
852
853    fn sub(self, rhs: Self) -> Self::Output {
854        Ok(match self {
855            Value::Int(v) => {
856                check_operands(&self, &rhs, "sub", |v| v.is_any_int())?;
857                Value::Int(v - rhs.to_int().unwrap())
858            },
859            Value::Int64(v) => {
860                check_operands(&self, &rhs, "sub", |v| v.is_any_int())?;
861                Value::Int64(v - rhs.to_int64().unwrap())
862            },
863            Value::Float32(v) => {
864                check_operands(&self, &rhs, "sub", |v| v.is_any_int_or_float())?;
865                Value::Float32(v - rhs.to_float32().unwrap())
866            },
867            Value::Float(v) => {
868                check_operands(&self, &rhs, "sub", |v| v.is_any_int_or_float())?;
869                Value::Float(v - rhs.to_float().unwrap())
870            },
871            Value::Decimal(d) => {
872                check_operands(&self, &rhs, "sub", |v| v.is_decimal())?;
873                Value::Decimal(d - rhs.as_decimal().unwrap())
874            },
875            _ => Err(operands_error_message(self, rhs, "sub"))?,
876        })
877    }
878}
879
880impl Mul for &Value {
881
882    type Output = Result<Value>;
883
884    fn mul(self, rhs: Self) -> Self::Output {
885        Ok(match self {
886            Value::Int(v) => {
887                check_operands(&self, &rhs, "mul", |v| v.is_any_int())?;
888                Value::Int(v * rhs.to_int().unwrap())
889            },
890            Value::Int64(v) => {
891                check_operands(&self, &rhs, "mul", |v| v.is_any_int())?;
892                Value::Int64(v * rhs.to_int64().unwrap())
893            },
894            Value::Float32(v) => {
895                check_operands(&self, &rhs, "mul", |v| v.is_any_int_or_float())?;
896                Value::Float32(v * rhs.to_float32().unwrap())
897            },
898            Value::Float(v) => {
899                check_operands(&self, &rhs, "mul", |v| v.is_any_int_or_float())?;
900                Value::Float(v * rhs.to_float().unwrap())
901            },
902            Value::Decimal(d) => {
903                check_operands(&self, &rhs, "mul", |v| v.is_decimal())?;
904                Value::Decimal(d * rhs.as_decimal().unwrap())
905            },
906            _ => Err(operands_error_message(self, rhs, "mul"))?,
907        })
908    }
909}
910
911impl Div for &Value {
912
913    type Output = Result<Value>;
914
915    fn div(self, rhs: Self) -> Self::Output {
916        Ok(match self {
917            Value::Int(v) => {
918                check_operands(&self, &rhs, "div", |v| v.is_any_int())?;
919                Value::Int(v / rhs.to_int().unwrap())
920            },
921            Value::Int64(v) => {
922                check_operands(&self, &rhs, "div", |v| v.is_any_int())?;
923                Value::Int64(v / rhs.to_int64().unwrap())
924            },
925            Value::Float32(v) => {
926                check_operands(&self, &rhs, "div", |v| v.is_any_int_or_float())?;
927                Value::Float32(v / rhs.to_float32().unwrap())
928            },
929            Value::Float(v) => {
930                check_operands(&self, &rhs, "div", |v| v.is_any_int_or_float())?;
931                Value::Float(v / rhs.to_float().unwrap())
932            },
933            Value::Decimal(d) => {
934                check_operands(&self, &rhs, "div", |v| v.is_decimal())?;
935                Value::Decimal(d / rhs.as_decimal().unwrap())
936            },
937            _ => Err(operands_error_message(self, rhs, "div"))?,
938        })
939    }
940}
941
942impl Rem for &Value {
943
944    type Output = Result<Value>;
945
946    fn rem(self, rhs: Self) -> Self::Output {
947        Ok(match self {
948            Value::Int(v) => {
949                check_operands(&self, &rhs, "rem", |v| v.is_any_int())?;
950                Value::Int(v % rhs.to_int().unwrap())
951            },
952            Value::Int64(v) => {
953                check_operands(&self, &rhs, "rem", |v| v.is_any_int())?;
954                Value::Int64(v % rhs.to_int64().unwrap())
955            },
956            Value::Float32(v) => {
957                check_operands(&self, &rhs, "rem", |v| v.is_any_int_or_float())?;
958                Value::Float32(v % rhs.to_float32().unwrap())
959            },
960            Value::Float(v) => {
961                check_operands(&self, &rhs, "rem", |v| v.is_any_int_or_float())?;
962                Value::Float(v % rhs.to_float().unwrap())
963            },
964            Value::Decimal(d) => {
965                check_operands(&self, &rhs, "rem", |v| v.is_decimal())?;
966                Value::Decimal(d % rhs.as_decimal().unwrap())
967            },
968            _ => Err(operands_error_message(self, rhs, "rem"))?,
969        })
970    }
971}
972
973impl Neg for &Value {
974
975    type Output = Result<Value>;
976
977    fn neg(self) -> Self::Output {
978        Ok(match self {
979            Value::Int(val) => Value::Int(-*val),
980            Value::Int64(val) => Value::Int64(-*val),
981            Value::Float32(val) => Value::Float32(-*val),
982            Value::Float(val) => Value::Float(-*val),
983            Value::Decimal(val) => Value::Decimal(val.neg()),
984            _ => Err(operand_error_message(self, "neg"))?,
985        })
986    }
987}
988
989impl Shl for &Value {
990
991    type Output = Result<Value>;
992
993    fn shl(self, rhs: Self) -> Self::Output {
994        Ok(match self {
995            Value::Int(v) => {
996                check_operands(&self, rhs, "shift left", |v| v.is_any_int())?;
997                Value::Int(v << rhs.as_int().unwrap())
998            },
999            Value::Int64(v) => {
1000                check_operands(&self, rhs, "shift left", |v| v.is_any_int())?;
1001                Value::Int64(v << rhs.as_int64().unwrap())
1002            },
1003            _ => Err(operand_error_message(self, "shift left"))?,
1004        })
1005    }
1006}
1007
1008impl Shr for &Value {
1009
1010    type Output = Result<Value>;
1011
1012    fn shr(self, rhs: Self) -> Self::Output {
1013        Ok(match self {
1014            Value::Int(v) => {
1015                check_operands(&self, rhs, "shift right", |v| v.is_any_int())?;
1016                Value::Int(v >> rhs.as_int().unwrap())
1017            },
1018            Value::Int64(v) => {
1019                check_operands(&self, rhs, "shift right", |v| v.is_any_int())?;
1020                Value::Int64(v >> rhs.as_int64().unwrap())
1021            },
1022            _ => Err(operand_error_message(self, "shift right"))?,
1023        })
1024    }
1025}
1026
1027impl BitAnd for &Value {
1028
1029    type Output = Result<Value>;
1030
1031    fn bitand(self, rhs: Self) -> Self::Output {
1032        Ok(match self {
1033            Value::Int(v) => {
1034                check_operands(&self, rhs, "bitand", |v| v.is_any_int())?;
1035                Value::Int(v & rhs.as_int().unwrap())
1036            },
1037            Value::Int64(v) => {
1038                check_operands(&self, rhs, "bitand", |v| v.is_any_int())?;
1039                Value::Int64(v & rhs.as_int64().unwrap())
1040            },
1041            Value::OptionVariant(e) => {
1042                check_enum_operands("bitand", self, rhs)?;
1043                Value::OptionVariant((e & rhs.as_option_variant().unwrap())?)
1044            }
1045            _ => Err(operand_error_message(self, "bitand"))?,
1046        })
1047    }
1048}
1049
1050impl BitXor for &Value {
1051
1052    type Output = Result<Value>;
1053
1054    fn bitxor(self, rhs: Self) -> Self::Output {
1055        Ok(match self {
1056            Value::Int(v) => {
1057                check_operands(&self, rhs, "bitxor", |v| v.is_any_int())?;
1058                Value::Int(v ^ rhs.as_int().unwrap())
1059            },
1060            Value::Int64(v) => {
1061                check_operands(&self, rhs, "bitxor", |v| v.is_any_int())?;
1062                Value::Int64(v ^ rhs.as_int64().unwrap())
1063            },
1064            Value::OptionVariant(e) => {
1065                check_enum_operands("bitxor", self, rhs)?;
1066                Value::OptionVariant((e ^ rhs.as_option_variant().unwrap())?)
1067            }
1068            _ => Err(operand_error_message(self, "bitxor"))?,
1069        })
1070    }
1071}
1072
1073impl BitOr for &Value {
1074
1075    type Output = Result<Value>;
1076
1077    fn bitor(self, rhs: Self) -> Self::Output {
1078        Ok(match self {
1079            Value::Int(v) => {
1080                check_operands(&self, rhs, "bitor", |v| v.is_any_int())?;
1081                Value::Int(v | rhs.as_int().unwrap())
1082            },
1083            Value::Int64(v) => {
1084                check_operands(&self, rhs, "bitor", |v| v.is_any_int())?;
1085                Value::Int64(v | rhs.as_int64().unwrap())
1086            },
1087            Value::OptionVariant(e) => {
1088                check_enum_operands("bitor", self, rhs)?;
1089                Value::OptionVariant((e | rhs.as_option_variant().unwrap())?)
1090            }
1091            _ => Err(operand_error_message(self, "bitor"))?,
1092        })
1093    }
1094}
1095
1096// This is bit neg
1097impl Not for &Value {
1098
1099    type Output = Result<Value>;
1100
1101    fn not(self) -> Self::Output {
1102        Ok(match self {
1103            Value::Int(val) => Value::Int(-*val),
1104            Value::Int64(val) => Value::Int64(-*val),
1105            Value::Float32(val) => Value::Float32(-*val),
1106            Value::Float(val) => Value::Float(-*val),
1107            Value::Decimal(val) => Value::Decimal(val.neg()),
1108            Value::OptionVariant(e) => Value::OptionVariant(e.not()),
1109            _ => Err(operand_error_message(self, "bitneg"))?,
1110        })
1111    }
1112}
1113
1114impl PartialEq for Value {
1115
1116    fn eq(&self, other: &Self) -> bool {
1117        use Value::*;
1118        if self.is_any_int() && other.is_any_int() {
1119            return self.to_int64().unwrap() == other.to_int64().unwrap();
1120        }
1121        if self.is_any_int_or_float() && other.is_any_int_or_float() {
1122            return self.to_float().unwrap() == other.to_float().unwrap();
1123        }
1124        match (self, other) {
1125            (Null, Null) => true,
1126            (Bool(s), Bool(o)) => s == o,
1127            (Decimal(s), Decimal(o)) => s == o,
1128            (ObjectId(s), ObjectId(o)) => s == o,
1129            (String(s), String(o)) => s == o,
1130            (Date(s), Date(o)) => s == o,
1131            (DateTime(s), DateTime(o)) => s == o,
1132            (Array(s), Array(o)) => s == o,
1133            (Dictionary(s), Dictionary(o)) => s == o,
1134            (Range(s), Range(o)) => s == o,
1135            (Tuple(s), Tuple(o)) => s == o,
1136            (InterfaceEnumVariant(s), InterfaceEnumVariant(o)) => s == o,
1137            (OptionVariant(s), OptionVariant(o)) => s.value == o.value,
1138            (Regex(s), Regex(o)) => s.as_str() == o.as_str(),
1139            (File(s), File(o)) => s == o,
1140            _ => false,
1141        }
1142    }
1143}
1144
1145impl PartialOrd for Value {
1146
1147    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1148        use Value::*;
1149        if self.is_any_int() && other.is_any_int() {
1150            return self.to_int64().unwrap().partial_cmp(&other.to_int64().unwrap());
1151        }
1152        if self.is_any_int_or_float() && other.is_any_int_or_float() {
1153            return self.to_float().unwrap().partial_cmp(&other.to_float().unwrap());
1154        }
1155        match (self, other) {
1156            (Null, Null) => Some(Ordering::Equal),
1157            (Bool(s), Bool(o)) => s.partial_cmp(o),
1158            (Decimal(s), Decimal(o)) => s.partial_cmp(o),
1159            (ObjectId(s), ObjectId(o)) => s.partial_cmp(o),
1160            (String(s), String(o)) => s.partial_cmp(o),
1161            (Date(s), Date(o)) => s.partial_cmp(o),
1162            (DateTime(s), DateTime(o)) => s.partial_cmp(o),
1163            (Array(s), Array(o)) => s.partial_cmp(o),
1164            (Tuple(s), Tuple(o)) => s.partial_cmp(o),
1165            (InterfaceEnumVariant(s), InterfaceEnumVariant(o)) => s.value.partial_cmp(&o.value),
1166            (OptionVariant(s), OptionVariant(o)) => s.value.partial_cmp(&o.value),
1167            _ => None,
1168        }
1169    }
1170}
1171
1172impl AsRef<Value> for Value {
1173
1174    fn as_ref(&self) -> &Value {
1175        &self
1176    }
1177}
1178
1179impl Display for Value {
1180
1181    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1182        match self {
1183            Value::Null => f.write_str("null"),
1184            Value::Bool(b) => Display::fmt(b, f),
1185            Value::Int(i) => Display::fmt(i, f),
1186            Value::Int64(i) => Display::fmt(i, f),
1187            Value::Float32(n) => Display::fmt(n, f),
1188            Value::Float(n) => Display::fmt(n, f),
1189            Value::Decimal(d) => {
1190                f.write_str("Decimal(\"")?;
1191                Display::fmt(d, f)?;
1192                f.write_str("\"")
1193            },
1194            Value::ObjectId(o) => {
1195                f.write_str("ObjectId(\"")?;
1196                Display::fmt(o, f)?;
1197                f.write_str("\"")
1198            },
1199            Value::String(s) => {
1200                f.write_str(&format!("\"{}\"", s.replace("\"", "\\\"")))
1201            }
1202            Value::Date(d) => f.write_str(&format!("Date(\"{}\")", d.to_string())),
1203            Value::DateTime(d) => f.write_str(&format!("DateTime(\"{}\")", d.to_rfc3339_opts(SecondsFormat::Millis, true))),
1204            Value::Array(a) => {
1205                f.write_str(&("[".to_string() + a.iter().map(|v| format!("{v}")).join(", ").as_str() + "]"))
1206            }
1207            Value::Dictionary(m) => {
1208                f.write_str(&("{".to_string() + m.iter().map(|(k, v)| format!("\"{k}\": {}", format!("{v}"))).join(", ").as_str() + "}"))
1209            }
1210            Value::Range(r) => Display::fmt(r, f),
1211            Value::Tuple(t) => {
1212                f.write_str("(")?;
1213                for (i, v) in t.iter().enumerate() {
1214                    Display::fmt(v, f)?;
1215                    if i != t.len() - 1 {
1216                        f.write_str(", ")?;
1217                    }
1218                }
1219                if t.len() == 1 {
1220                    f.write_str(",")?;
1221                }
1222                f.write_str(")")
1223            }
1224            Value::InterfaceEnumVariant(e) => {
1225                Display::fmt(e, f)
1226            }
1227            Value::OptionVariant(o) => {
1228                f.write_str(&o.display)
1229            }
1230            Value::Regex(r) => {
1231                f.write_str("/")?;
1232                f.write_str(&format!("{}", r.as_str().replace("/", "\\/")))?;
1233                f.write_str("/")
1234            }
1235            Value::File(file) => Display::fmt(file, f),
1236            Value::ModelObject(model_object) => Display::fmt(model_object, f),
1237            Value::StructObject(struct_object) => Display::fmt(struct_object, f),
1238            Value::Pipeline(pipeline) => Display::fmt(pipeline, f),
1239            Value::Type(t) => Display::fmt(t, f),
1240        }
1241    }
1242}
1243
1244
1245fn do_cast(value: &Value, target: &Type, namespace: &Namespace) -> Value {
1246    match target {
1247        Type::Int => do_cast_to_int(value),
1248        Type::Int64 => do_cast_to_int64(value),
1249        Type::Float32 => do_cast_to_float32(value),
1250        Type::Float => do_cast_to_float(value),
1251        Type::Union(types) => {
1252            let mut result = value.clone();
1253            for t in types {
1254                result = do_cast(&result, t, namespace);
1255            }
1256            result
1257        }
1258        Type::Enumerable(enumerable) => {
1259            if let Some(array) = value.as_array() {
1260                Value::Array(array.iter().map(|v| do_cast(v, enumerable.as_ref(), namespace)).collect())
1261            } else {
1262                do_cast(value, enumerable.as_ref(), namespace)
1263            }
1264        }
1265        Type::Optional(inner) => do_cast(value, inner.as_ref(), namespace),
1266        Type::Array(inner) => {
1267            if let Some(array) = value.as_array() {
1268                Value::Array(array.iter().map(|v| do_cast(v, inner.as_ref(), namespace)).collect())
1269            } else {
1270                value.clone()
1271            }
1272        }
1273        Type::Dictionary(inner) => {
1274            if let Some(dictionary) = value.as_dictionary() {
1275                Value::Dictionary(dictionary.iter().map(|(k, v)| (k.clone(), do_cast(v, inner.as_ref(), namespace))).collect())
1276            } else {
1277                value.clone()
1278            }
1279        }
1280        Type::Tuple(types) => {
1281            let undetermined = Type::Undetermined;
1282            if let Some(array) = value.as_array() {
1283                Value::Tuple(array.iter().enumerate().map(|(i, v)| do_cast(v, types.get(i).unwrap_or(&undetermined), namespace)).collect())
1284            } else if let Some(array) = value.as_tuple() {
1285                Value::Tuple(array.iter().enumerate().map(|(i, v)| do_cast(v, types.get(i).unwrap_or(&undetermined), namespace)).collect())
1286            } else {
1287                value.clone()
1288            }
1289        }
1290        Type::Range(inner) => {
1291            if let Some(range) = value.as_range() {
1292                Value::Range(Range {
1293                    start: Box::new(do_cast(range.start.as_ref(), inner.as_ref(), namespace)),
1294                    end: Box::new(do_cast(range.end.as_ref(), inner.as_ref(), namespace)),
1295                    closed: range.closed
1296                })
1297            } else {
1298                value.clone()
1299            }
1300        }
1301        Type::SynthesizedShape(shape) => {
1302            if let Some(dictionary) = value.as_dictionary() {
1303                Value::Dictionary(do_cast_shape(dictionary, shape, namespace))
1304            } else {
1305                value.clone()
1306            }
1307        }
1308        Type::SynthesizedShapeReference(reference) => {
1309            if let Some(definition) = reference.fetch_synthesized_definition_for_namespace(namespace) {
1310                do_cast(value, definition, namespace)
1311            } else {
1312                value.clone()
1313            }
1314        }
1315        Type::InterfaceObject(reference, gens) => {
1316            if let Some(dictionary) = value.as_dictionary() {
1317                let interface = namespace.interface_at_path(reference.string_path()).unwrap();
1318                let shape = interface.shape_from_generics(gens);
1319                Value::Dictionary(do_cast_shape(dictionary, &shape, namespace))
1320            } else {
1321                value.clone()
1322            }
1323        }
1324        _ => value.clone(),
1325    }
1326}
1327
1328fn do_cast_to_int(value: &Value) -> Value {
1329    match value {
1330        Value::Float(f) => Value::Int(*f as i32),
1331        Value::Float32(f) => Value::Int(*f as i32),
1332        Value::Int64(i) => Value::Int(*i as i32),
1333        _ => value.clone()
1334    }
1335}
1336
1337fn do_cast_to_int64(value: &Value) -> Value {
1338    match value {
1339        Value::Float(f) => Value::Int64(*f as i64),
1340        Value::Float32(f) => Value::Int64(*f as i64),
1341        Value::Int(i) => Value::Int64(*i as i64),
1342        _ => value.clone(),
1343    }
1344}
1345
1346fn do_cast_to_float32(value: &Value) -> Value {
1347    match value {
1348        Value::Float(f) => Value::Float32(*f as f32),
1349        Value::Int(i) => Value::Float32(*i as f32),
1350        Value::Int64(i) => Value::Float32(*i as f32),
1351        _ => value.clone(),
1352    }
1353}
1354
1355fn do_cast_to_float(value: &Value) -> Value {
1356    match value {
1357        Value::Float32(f) => Value::Float(*f as f64),
1358        Value::Int(i) => Value::Float(*i as f64),
1359        Value::Int64(i) => Value::Float(*i as f64),
1360        _ => value.clone(),
1361    }
1362}
1363
1364fn do_cast_shape(dictionary: &IndexMap<String, Value>, shape: &SynthesizedShape, namespace: &Namespace) -> IndexMap<String, Value> {
1365    let undetermined = Type::Undetermined;
1366    dictionary.iter().map(|(k, v)| (k.clone(), do_cast(v, shape.get(k).unwrap_or(&undetermined), namespace))).collect()
1367}