1use std::cmp::Ordering;
62use std::collections::BTreeMap;
63use std::fmt;
64use std::sync::Arc;
65
66use super::message::MessageValue;
67use super::EvalError;
68use crate::types::{CelType, CelValue};
69
70#[derive(Debug, Clone, PartialEq, Eq)]
72pub struct ValueError {
73 pub expected: &'static str,
75 pub found: String,
77}
78
79impl std::fmt::Display for ValueError {
80 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81 write!(f, "expected {}, found {}", self.expected, self.found)
82 }
83}
84
85impl std::error::Error for ValueError {}
86
87#[derive(Debug, Clone)]
93pub enum Value {
94 Null,
96 Bool(bool),
98 Int(i64),
100 UInt(u64),
102 Double(f64),
104 String(Arc<str>),
106 Bytes(Arc<[u8]>),
108 List(Arc<[Value]>),
110 Map(Arc<ValueMap>),
112 Timestamp(Timestamp),
114 Duration(Duration),
116 Type(TypeValue),
118 Optional(OptionalValue),
120 Message(Box<dyn MessageValue>),
122 Enum(EnumValue),
124 Error(Arc<EvalError>),
126}
127
128#[derive(Debug, Clone)]
133pub struct EnumValue {
134 pub type_name: Arc<str>,
136 pub value: i32,
138}
139
140impl EnumValue {
141 pub fn new(type_name: impl Into<Arc<str>>, value: i32) -> Self {
143 Self {
144 type_name: type_name.into(),
145 value,
146 }
147 }
148}
149
150impl PartialEq for EnumValue {
151 fn eq(&self, other: &Self) -> bool {
152 self.type_name == other.type_name && self.value == other.value
153 }
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq)]
158pub struct Timestamp {
159 pub seconds: i64,
161 pub nanos: i32,
163}
164
165impl Timestamp {
166 pub const MIN_SECONDS: i64 = -62135596800;
169
170 pub const MAX_SECONDS: i64 = 253402300799;
173
174 pub fn new(seconds: i64, nanos: i32) -> Self {
176 Self { seconds, nanos }
177 }
178
179 pub fn from_seconds(seconds: i64) -> Self {
181 Self { seconds, nanos: 0 }
182 }
183
184 pub fn is_before(&self, other: &Timestamp) -> bool {
186 (self.seconds, self.nanos) < (other.seconds, other.nanos)
187 }
188
189 pub fn is_after(&self, other: &Timestamp) -> bool {
191 (self.seconds, self.nanos) > (other.seconds, other.nanos)
192 }
193
194 pub fn is_valid(&self) -> bool {
196 self.seconds >= Self::MIN_SECONDS && self.seconds <= Self::MAX_SECONDS
197 }
198
199 pub fn to_datetime_utc(&self) -> Option<chrono::DateTime<chrono::Utc>> {
201 chrono::DateTime::from_timestamp(self.seconds, self.nanos as u32)
202 }
203
204 pub fn from_datetime<Tz: chrono::TimeZone>(dt: &chrono::DateTime<Tz>) -> Self {
206 Self {
207 seconds: dt.timestamp(),
208 nanos: dt.timestamp_subsec_nanos() as i32,
209 }
210 }
211
212 pub fn to_nanos(&self) -> Option<i128> {
214 let secs = self.seconds as i128;
215 let nanos = self.nanos as i128;
216 secs.checked_mul(1_000_000_000).map(|s| s + nanos)
217 }
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq)]
222pub struct Duration {
223 pub seconds: i64,
225 pub nanos: i32,
228}
229
230impl Duration {
231 pub const MAX_SECONDS: i64 = 315_537_897_598;
236
237 pub const MIN_SECONDS: i64 = -315_537_897_598;
239
240 pub fn new(seconds: i64, nanos: i32) -> Self {
242 Self { seconds, nanos }
243 }
244
245 pub fn from_seconds(seconds: i64) -> Self {
247 Self { seconds, nanos: 0 }
248 }
249
250 pub fn from_nanos(nanos: i64) -> Self {
252 let seconds = nanos / 1_000_000_000;
253 let nanos = (nanos % 1_000_000_000) as i32;
254 Self { seconds, nanos }
255 }
256
257 pub fn to_nanos(&self) -> i64 {
259 self.seconds
260 .saturating_mul(1_000_000_000)
261 .saturating_add(self.nanos as i64)
262 }
263
264 pub fn is_negative(&self) -> bool {
266 self.seconds < 0 || (self.seconds == 0 && self.nanos < 0)
267 }
268
269 pub fn is_valid(&self) -> bool {
271 self.seconds >= Self::MIN_SECONDS && self.seconds <= Self::MAX_SECONDS
272 }
273
274 pub fn to_chrono(&self) -> chrono::Duration {
276 chrono::Duration::seconds(self.seconds) + chrono::Duration::nanoseconds(self.nanos as i64)
277 }
278
279 pub fn from_chrono(d: chrono::Duration) -> Self {
281 let total_nanos = d.num_nanoseconds().unwrap_or(0);
282 Self::from_nanos(total_nanos)
283 }
284
285 pub fn get_hours(&self) -> i64 {
287 self.total_seconds() / 3600
288 }
289
290 pub fn get_minutes(&self) -> i64 {
292 self.total_seconds() / 60
293 }
294
295 pub fn total_seconds(&self) -> i64 {
297 self.seconds
298 }
299
300 pub fn get_milliseconds(&self) -> i64 {
302 let ms = if self.nanos >= 0 {
304 self.nanos / 1_000_000
305 } else {
306 -(-self.nanos / 1_000_000)
307 };
308 ms as i64
309 }
310}
311
312#[derive(Debug, Clone, PartialEq, Eq)]
314pub struct TypeValue {
315 pub name: Arc<str>,
317}
318
319impl TypeValue {
320 pub fn new(name: impl Into<Arc<str>>) -> Self {
322 Self { name: name.into() }
323 }
324
325 pub fn null_type() -> Self {
327 Self::new("null_type")
328 }
329 pub fn bool_type() -> Self {
330 Self::new("bool")
331 }
332 pub fn int_type() -> Self {
333 Self::new("int")
334 }
335 pub fn uint_type() -> Self {
336 Self::new("uint")
337 }
338 pub fn double_type() -> Self {
339 Self::new("double")
340 }
341 pub fn string_type() -> Self {
342 Self::new("string")
343 }
344 pub fn bytes_type() -> Self {
345 Self::new("bytes")
346 }
347 pub fn list_type() -> Self {
348 Self::new("list")
349 }
350 pub fn map_type() -> Self {
351 Self::new("map")
352 }
353 pub fn timestamp_type() -> Self {
354 Self::new("google.protobuf.Timestamp")
355 }
356 pub fn duration_type() -> Self {
357 Self::new("google.protobuf.Duration")
358 }
359 pub fn type_type() -> Self {
360 Self::new("type")
361 }
362 pub fn optional_type() -> Self {
363 Self::new("optional")
364 }
365}
366
367#[derive(Debug, Clone)]
369pub enum OptionalValue {
370 None,
372 Some(Box<Value>),
374}
375
376impl OptionalValue {
377 pub fn none() -> Self {
379 OptionalValue::None
380 }
381
382 pub fn some(value: Value) -> Self {
384 OptionalValue::Some(Box::new(value))
385 }
386
387 pub fn is_present(&self) -> bool {
389 matches!(self, OptionalValue::Some(_))
390 }
391
392 pub fn as_value(&self) -> Option<&Value> {
394 match self {
395 OptionalValue::None => None,
396 OptionalValue::Some(v) => Some(v),
397 }
398 }
399
400 pub fn unwrap_or(self, default: Value) -> Value {
402 match self {
403 OptionalValue::None => default,
404 OptionalValue::Some(v) => *v,
405 }
406 }
407}
408
409#[derive(Debug, Clone, Default)]
413pub struct ValueMap {
414 entries: BTreeMap<MapKey, Value>,
415}
416
417#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
421pub enum MapKey {
422 Bool(bool),
423 Int(i64),
424 UInt(u64),
425 String(Arc<str>),
426}
427
428impl MapKey {
429 pub fn from_value(value: &Value) -> Option<Self> {
431 match value {
432 Value::Bool(b) => Some(MapKey::Bool(*b)),
433 Value::Int(i) => Some(MapKey::Int(*i)),
434 Value::UInt(u) => Some(MapKey::UInt(*u)),
435 Value::String(s) => Some(MapKey::String(s.clone())),
436 _ => None,
437 }
438 }
439
440 pub fn to_value(&self) -> Value {
442 match self {
443 MapKey::Bool(b) => Value::Bool(*b),
444 MapKey::Int(i) => Value::Int(*i),
445 MapKey::UInt(u) => Value::UInt(*u),
446 MapKey::String(s) => Value::String(s.clone()),
447 }
448 }
449}
450
451impl From<&str> for MapKey {
452 fn from(s: &str) -> Self {
453 MapKey::String(Arc::from(s))
454 }
455}
456
457impl From<String> for MapKey {
458 fn from(s: String) -> Self {
459 MapKey::String(Arc::from(s))
460 }
461}
462
463impl From<Arc<str>> for MapKey {
464 fn from(s: Arc<str>) -> Self {
465 MapKey::String(s)
466 }
467}
468
469impl From<bool> for MapKey {
470 fn from(b: bool) -> Self {
471 MapKey::Bool(b)
472 }
473}
474
475impl From<i64> for MapKey {
476 fn from(i: i64) -> Self {
477 MapKey::Int(i)
478 }
479}
480
481impl From<u64> for MapKey {
482 fn from(u: u64) -> Self {
483 MapKey::UInt(u)
484 }
485}
486
487impl From<i32> for MapKey {
488 fn from(i: i32) -> Self {
489 MapKey::Int(i as i64)
490 }
491}
492
493impl From<u32> for MapKey {
494 fn from(u: u32) -> Self {
495 MapKey::UInt(u as u64)
496 }
497}
498
499impl ValueMap {
500 pub fn new() -> Self {
502 Self {
503 entries: BTreeMap::new(),
504 }
505 }
506
507 pub fn from_entries(entries: impl IntoIterator<Item = (MapKey, Value)>) -> Self {
509 Self {
510 entries: entries.into_iter().collect(),
511 }
512 }
513
514 pub fn get(&self, key: &MapKey) -> Option<&Value> {
516 self.entries.get(key)
517 }
518
519 pub fn insert(&mut self, key: MapKey, value: Value) {
521 self.entries.insert(key, value);
522 }
523
524 pub fn contains_key(&self, key: &MapKey) -> bool {
526 self.entries.contains_key(key)
527 }
528
529 pub fn get_with_numeric_coercion(&self, key: &MapKey) -> Option<&Value> {
532 if let Some(v) = self.entries.get(key) {
533 return Some(v);
534 }
535 match key {
536 MapKey::Int(i) => {
537 if *i >= 0 {
538 self.entries.get(&MapKey::UInt(*i as u64))
539 } else {
540 None
541 }
542 }
543 MapKey::UInt(u) => {
544 if *u <= i64::MAX as u64 {
545 self.entries.get(&MapKey::Int(*u as i64))
546 } else {
547 None
548 }
549 }
550 _ => None,
551 }
552 }
553
554 pub fn contains_key_with_numeric_coercion(&self, key: &MapKey) -> bool {
556 self.get_with_numeric_coercion(key).is_some()
557 }
558
559 pub fn len(&self) -> usize {
561 self.entries.len()
562 }
563
564 pub fn is_empty(&self) -> bool {
566 self.entries.is_empty()
567 }
568
569 pub fn iter(&self) -> impl Iterator<Item = (&MapKey, &Value)> {
571 self.entries.iter()
572 }
573
574 pub fn keys(&self) -> impl Iterator<Item = &MapKey> {
576 self.entries.keys()
577 }
578
579 pub fn values(&self) -> impl Iterator<Item = &Value> {
581 self.entries.values()
582 }
583}
584
585impl Value {
588 pub fn map<K, V>(entries: impl IntoIterator<Item = (K, V)>) -> Self
608 where
609 K: Into<MapKey>,
610 V: Into<Value>,
611 {
612 Value::Map(Arc::new(ValueMap::from_entries(
613 entries.into_iter().map(|(k, v)| (k.into(), v.into())),
614 )))
615 }
616
617 pub fn list<T>(items: impl IntoIterator<Item = T>) -> Self
634 where
635 T: Into<Value>,
636 {
637 Value::List(Arc::from(
638 items.into_iter().map(Into::into).collect::<Vec<_>>(),
639 ))
640 }
641
642 pub fn timestamp(seconds: i64, nanos: i32) -> Self {
644 Value::Timestamp(Timestamp::new(seconds, nanos))
645 }
646
647 pub fn duration(seconds: i64, nanos: i32) -> Self {
649 Value::Duration(Duration::new(seconds, nanos))
650 }
651
652 pub fn new_type(name: impl Into<Arc<str>>) -> Self {
654 Value::Type(TypeValue::new(name))
655 }
656
657 pub fn optional_none() -> Self {
659 Value::Optional(OptionalValue::None)
660 }
661
662 pub fn optional_some(value: Value) -> Self {
664 Value::Optional(OptionalValue::some(value))
665 }
666
667 pub fn from_option<T: Into<Value>>(opt: Option<T>) -> Self {
679 match opt {
680 Some(v) => Value::optional_some(v.into()),
681 None => Value::optional_none(),
682 }
683 }
684
685 pub fn error(err: impl Into<EvalError>) -> Self {
687 Value::Error(Arc::new(err.into()))
688 }
689}
690
691impl From<bool> for Value {
694 fn from(b: bool) -> Self {
695 Value::Bool(b)
696 }
697}
698
699impl From<i64> for Value {
700 fn from(i: i64) -> Self {
701 Value::Int(i)
702 }
703}
704
705impl From<u64> for Value {
706 fn from(u: u64) -> Self {
707 Value::UInt(u)
708 }
709}
710
711impl From<i8> for Value {
713 fn from(i: i8) -> Self {
714 Value::Int(i as i64)
715 }
716}
717
718impl From<i16> for Value {
719 fn from(i: i16) -> Self {
720 Value::Int(i as i64)
721 }
722}
723
724impl From<i32> for Value {
725 fn from(i: i32) -> Self {
726 Value::Int(i as i64)
727 }
728}
729
730impl From<isize> for Value {
731 fn from(i: isize) -> Self {
732 Value::Int(i as i64)
733 }
734}
735
736impl From<u8> for Value {
738 fn from(u: u8) -> Self {
739 Value::UInt(u as u64)
740 }
741}
742
743impl From<u16> for Value {
744 fn from(u: u16) -> Self {
745 Value::UInt(u as u64)
746 }
747}
748
749impl From<u32> for Value {
750 fn from(u: u32) -> Self {
751 Value::UInt(u as u64)
752 }
753}
754
755impl From<usize> for Value {
756 fn from(u: usize) -> Self {
757 Value::UInt(u as u64)
758 }
759}
760
761impl From<f64> for Value {
762 fn from(d: f64) -> Self {
763 Value::Double(d)
764 }
765}
766
767impl From<&str> for Value {
768 fn from(s: &str) -> Self {
769 Value::String(Arc::from(s))
770 }
771}
772
773impl From<String> for Value {
774 fn from(s: String) -> Self {
775 Value::String(Arc::from(s))
776 }
777}
778
779impl From<Arc<str>> for Value {
780 fn from(s: Arc<str>) -> Self {
781 Value::String(s)
782 }
783}
784
785impl From<&[u8]> for Value {
786 fn from(b: &[u8]) -> Self {
787 Value::Bytes(Arc::from(b))
788 }
789}
790
791impl From<Vec<u8>> for Value {
792 fn from(b: Vec<u8>) -> Self {
793 Value::Bytes(Arc::from(b))
794 }
795}
796
797impl From<Arc<[u8]>> for Value {
798 fn from(b: Arc<[u8]>) -> Self {
799 Value::Bytes(b)
800 }
801}
802
803impl From<Vec<Value>> for Value {
804 fn from(v: Vec<Value>) -> Self {
805 Value::List(Arc::from(v))
806 }
807}
808
809impl From<Timestamp> for Value {
810 fn from(t: Timestamp) -> Self {
811 Value::Timestamp(t)
812 }
813}
814
815impl From<Duration> for Value {
816 fn from(d: Duration) -> Self {
817 Value::Duration(d)
818 }
819}
820
821impl From<EvalError> for Value {
822 fn from(e: EvalError) -> Self {
823 Value::Error(Arc::new(e))
824 }
825}
826
827impl From<CelValue> for Value {
828 fn from(cv: CelValue) -> Self {
829 match cv {
830 CelValue::Null => Value::Null,
831 CelValue::Bool(b) => Value::Bool(b),
832 CelValue::Int(i) => Value::Int(i),
833 CelValue::UInt(u) => Value::UInt(u),
834 CelValue::Double(d) => Value::Double(d),
835 CelValue::String(s) => Value::String(Arc::from(s)),
836 CelValue::Bytes(b) => Value::Bytes(Arc::from(b)),
837 }
838 }
839}
840
841impl<T: Into<Value>> From<Option<T>> for Value {
842 fn from(opt: Option<T>) -> Self {
843 match opt {
844 Some(v) => v.into(),
845 None => Value::Null,
846 }
847 }
848}
849
850impl TryFrom<Value> for bool {
853 type Error = ValueError;
854 fn try_from(v: Value) -> Result<Self, Self::Error> {
855 match v {
856 Value::Bool(b) => Ok(b),
857 other => Err(ValueError {
858 expected: "bool",
859 found: other.type_value().name.to_string(),
860 }),
861 }
862 }
863}
864
865impl TryFrom<&Value> for bool {
866 type Error = ValueError;
867 fn try_from(v: &Value) -> Result<Self, Self::Error> {
868 match v {
869 Value::Bool(b) => Ok(*b),
870 other => Err(ValueError {
871 expected: "bool",
872 found: other.type_value().name.to_string(),
873 }),
874 }
875 }
876}
877
878impl TryFrom<Value> for i64 {
879 type Error = ValueError;
880 fn try_from(v: Value) -> Result<Self, Self::Error> {
881 match v {
882 Value::Int(i) => Ok(i),
883 other => Err(ValueError {
884 expected: "int",
885 found: other.type_value().name.to_string(),
886 }),
887 }
888 }
889}
890
891impl TryFrom<&Value> for i64 {
892 type Error = ValueError;
893 fn try_from(v: &Value) -> Result<Self, Self::Error> {
894 match v {
895 Value::Int(i) => Ok(*i),
896 other => Err(ValueError {
897 expected: "int",
898 found: other.type_value().name.to_string(),
899 }),
900 }
901 }
902}
903
904impl TryFrom<Value> for u64 {
905 type Error = ValueError;
906 fn try_from(v: Value) -> Result<Self, Self::Error> {
907 match v {
908 Value::UInt(u) => Ok(u),
909 other => Err(ValueError {
910 expected: "uint",
911 found: other.type_value().name.to_string(),
912 }),
913 }
914 }
915}
916
917impl TryFrom<&Value> for u64 {
918 type Error = ValueError;
919 fn try_from(v: &Value) -> Result<Self, Self::Error> {
920 match v {
921 Value::UInt(u) => Ok(*u),
922 other => Err(ValueError {
923 expected: "uint",
924 found: other.type_value().name.to_string(),
925 }),
926 }
927 }
928}
929
930impl TryFrom<Value> for f64 {
931 type Error = ValueError;
932 fn try_from(v: Value) -> Result<Self, Self::Error> {
933 match v {
934 Value::Double(d) => Ok(d),
935 other => Err(ValueError {
936 expected: "double",
937 found: other.type_value().name.to_string(),
938 }),
939 }
940 }
941}
942
943impl TryFrom<&Value> for f64 {
944 type Error = ValueError;
945 fn try_from(v: &Value) -> Result<Self, Self::Error> {
946 match v {
947 Value::Double(d) => Ok(*d),
948 other => Err(ValueError {
949 expected: "double",
950 found: other.type_value().name.to_string(),
951 }),
952 }
953 }
954}
955
956impl TryFrom<Value> for String {
957 type Error = ValueError;
958 fn try_from(v: Value) -> Result<Self, Self::Error> {
959 match v {
960 Value::String(s) => Ok(s.to_string()),
961 other => Err(ValueError {
962 expected: "string",
963 found: other.type_value().name.to_string(),
964 }),
965 }
966 }
967}
968
969impl<'a> TryFrom<&'a Value> for &'a str {
970 type Error = ValueError;
971 fn try_from(v: &'a Value) -> Result<Self, Self::Error> {
972 match v {
973 Value::String(s) => Ok(s),
974 other => Err(ValueError {
975 expected: "string",
976 found: other.type_value().name.to_string(),
977 }),
978 }
979 }
980}
981
982impl<'a> TryFrom<&'a Value> for &'a [u8] {
983 type Error = ValueError;
984 fn try_from(v: &'a Value) -> Result<Self, Self::Error> {
985 match v {
986 Value::Bytes(b) => Ok(b),
987 other => Err(ValueError {
988 expected: "bytes",
989 found: other.type_value().name.to_string(),
990 }),
991 }
992 }
993}
994
995impl TryFrom<Value> for Timestamp {
996 type Error = ValueError;
997 fn try_from(v: Value) -> Result<Self, Self::Error> {
998 match v {
999 Value::Timestamp(t) => Ok(t),
1000 other => Err(ValueError {
1001 expected: "timestamp",
1002 found: other.type_value().name.to_string(),
1003 }),
1004 }
1005 }
1006}
1007
1008impl TryFrom<&Value> for Timestamp {
1009 type Error = ValueError;
1010 fn try_from(v: &Value) -> Result<Self, Self::Error> {
1011 match v {
1012 Value::Timestamp(t) => Ok(*t),
1013 other => Err(ValueError {
1014 expected: "timestamp",
1015 found: other.type_value().name.to_string(),
1016 }),
1017 }
1018 }
1019}
1020
1021impl TryFrom<Value> for Duration {
1022 type Error = ValueError;
1023 fn try_from(v: Value) -> Result<Self, Self::Error> {
1024 match v {
1025 Value::Duration(d) => Ok(d),
1026 other => Err(ValueError {
1027 expected: "duration",
1028 found: other.type_value().name.to_string(),
1029 }),
1030 }
1031 }
1032}
1033
1034impl TryFrom<&Value> for Duration {
1035 type Error = ValueError;
1036 fn try_from(v: &Value) -> Result<Self, Self::Error> {
1037 match v {
1038 Value::Duration(d) => Ok(*d),
1039 other => Err(ValueError {
1040 expected: "duration",
1041 found: other.type_value().name.to_string(),
1042 }),
1043 }
1044 }
1045}
1046
1047impl<'a> TryFrom<&'a Value> for &'a [Value] {
1048 type Error = ValueError;
1049 fn try_from(v: &'a Value) -> Result<Self, Self::Error> {
1050 match v {
1051 Value::List(l) => Ok(l),
1052 other => Err(ValueError {
1053 expected: "list",
1054 found: other.type_value().name.to_string(),
1055 }),
1056 }
1057 }
1058}
1059
1060impl<'a> TryFrom<&'a Value> for &'a ValueMap {
1061 type Error = ValueError;
1062 fn try_from(v: &'a Value) -> Result<Self, Self::Error> {
1063 match v {
1064 Value::Map(m) => Ok(m.as_ref()),
1065 other => Err(ValueError {
1066 expected: "map",
1067 found: other.type_value().name.to_string(),
1068 }),
1069 }
1070 }
1071}
1072
1073impl<'a> TryFrom<&'a Value> for &'a OptionalValue {
1074 type Error = ValueError;
1075 fn try_from(v: &'a Value) -> Result<Self, Self::Error> {
1076 match v {
1077 Value::Optional(o) => Ok(o),
1078 other => Err(ValueError {
1079 expected: "optional",
1080 found: other.type_value().name.to_string(),
1081 }),
1082 }
1083 }
1084}
1085
1086impl<'a> TryFrom<&'a Value> for &'a EvalError {
1087 type Error = ValueError;
1088 fn try_from(v: &'a Value) -> Result<Self, Self::Error> {
1089 match v {
1090 Value::Error(e) => Ok(e.as_ref()),
1091 other => Err(ValueError {
1092 expected: "error",
1093 found: other.type_value().name.to_string(),
1094 }),
1095 }
1096 }
1097}
1098
1099impl Value {
1102 pub fn cel_type(&self) -> CelType {
1104 match self {
1105 Value::Null => CelType::Null,
1106 Value::Bool(_) => CelType::Bool,
1107 Value::Int(_) => CelType::Int,
1108 Value::UInt(_) => CelType::UInt,
1109 Value::Double(_) => CelType::Double,
1110 Value::String(_) => CelType::String,
1111 Value::Bytes(_) => CelType::Bytes,
1112 Value::List(_) => CelType::list(CelType::Dyn),
1113 Value::Map(_) => CelType::map(CelType::Dyn, CelType::Dyn),
1114 Value::Timestamp(_) => CelType::Timestamp,
1115 Value::Duration(_) => CelType::Duration,
1116 Value::Type(_) => CelType::type_of(CelType::Dyn),
1117 Value::Optional(opt) => match opt {
1118 OptionalValue::None => CelType::optional(CelType::Dyn),
1119 OptionalValue::Some(v) => CelType::optional(v.cel_type()),
1120 },
1121 Value::Message(msg) => CelType::message(msg.type_name()),
1122 Value::Enum(ev) => CelType::enum_type(&ev.type_name),
1123 Value::Error(_) => CelType::Error,
1124 }
1125 }
1126
1127 pub fn type_value(&self) -> TypeValue {
1129 match self {
1130 Value::Null => TypeValue::null_type(),
1131 Value::Bool(_) => TypeValue::bool_type(),
1132 Value::Int(_) => TypeValue::int_type(),
1133 Value::UInt(_) => TypeValue::uint_type(),
1134 Value::Double(_) => TypeValue::double_type(),
1135 Value::String(_) => TypeValue::string_type(),
1136 Value::Bytes(_) => TypeValue::bytes_type(),
1137 Value::List(_) => TypeValue::list_type(),
1138 Value::Map(_) => TypeValue::map_type(),
1139 Value::Timestamp(_) => TypeValue::timestamp_type(),
1140 Value::Duration(_) => TypeValue::duration_type(),
1141 Value::Type(_) => TypeValue::type_type(),
1142 Value::Optional(_) => TypeValue::new("optional"),
1143 Value::Message(msg) => TypeValue::new(msg.type_name()),
1144 Value::Enum(ev) => TypeValue::new(ev.type_name.as_ref()),
1145 Value::Error(_) => TypeValue::new("error"),
1146 }
1147 }
1148
1149 pub fn is_error(&self) -> bool {
1151 matches!(self, Value::Error(_))
1152 }
1153
1154 pub fn is_null(&self) -> bool {
1156 matches!(self, Value::Null)
1157 }
1158
1159 pub fn is_truthy(&self) -> Option<bool> {
1163 match self {
1164 Value::Bool(b) => Some(*b),
1165 Value::Message(_) => Some(true), _ => None,
1167 }
1168 }
1169}
1170
1171impl PartialEq for Value {
1174 fn eq(&self, other: &Self) -> bool {
1175 match (self, other) {
1176 (Value::Null, Value::Null) => true,
1177 (Value::Bool(a), Value::Bool(b)) => a == b,
1178 (Value::Int(a), Value::Int(b)) => a == b,
1179 (Value::UInt(a), Value::UInt(b)) => a == b,
1180 (Value::Double(a), Value::Double(b)) => {
1181 a == b
1183 }
1184 (Value::String(a), Value::String(b)) => a == b,
1185 (Value::Bytes(a), Value::Bytes(b)) => a == b,
1186 (Value::List(a), Value::List(b)) => a == b,
1187 (Value::Map(a), Value::Map(b)) => {
1188 if a.len() != b.len() {
1189 return false;
1190 }
1191 for (key, val_a) in a.iter() {
1192 match b.get_with_numeric_coercion(key) {
1193 Some(val_b) if val_a == val_b => continue,
1194 _ => return false,
1195 }
1196 }
1197 true
1198 }
1199 (Value::Timestamp(a), Value::Timestamp(b)) => a == b,
1200 (Value::Duration(a), Value::Duration(b)) => a == b,
1201 (Value::Type(a), Value::Type(b)) => a == b,
1202 (Value::Optional(a), Value::Optional(b)) => match (a, b) {
1203 (OptionalValue::None, OptionalValue::None) => true,
1204 (OptionalValue::Some(va), OptionalValue::Some(vb)) => va == vb,
1205 _ => false,
1206 },
1207 (Value::Message(a), Value::Message(b)) => a.eq_message(b.as_ref()),
1208 (Value::Enum(a), Value::Enum(b)) => a == b,
1209 (Value::Int(a), Value::UInt(b)) => {
1211 if *a < 0 {
1212 false
1213 } else {
1214 *a as u64 == *b
1215 }
1216 }
1217 (Value::UInt(a), Value::Int(b)) => {
1218 if *b < 0 {
1219 false
1220 } else {
1221 *a == *b as u64
1222 }
1223 }
1224 (Value::Int(a), Value::Double(b)) => {
1225 if b.is_nan() {
1226 return false;
1227 }
1228 let a_f64 = *a as f64;
1229 a_f64 == *b && a_f64 as i64 == *a
1230 }
1231 (Value::Double(a), Value::Int(b)) => {
1232 if a.is_nan() {
1233 return false;
1234 }
1235 let b_f64 = *b as f64;
1236 *a == b_f64 && b_f64 as i64 == *b
1237 }
1238 (Value::UInt(a), Value::Double(b)) => {
1239 if b.is_nan() {
1240 return false;
1241 }
1242 let a_f64 = *a as f64;
1243 a_f64 == *b && a_f64 as u64 == *a
1244 }
1245 (Value::Double(a), Value::UInt(b)) => {
1246 if a.is_nan() {
1247 return false;
1248 }
1249 let b_f64 = *b as f64;
1250 *a == b_f64 && b_f64 as u64 == *b
1251 }
1252 (Value::Enum(e), Value::Int(i)) | (Value::Int(i), Value::Enum(e)) => {
1254 e.value as i64 == *i
1255 }
1256 (Value::Enum(e), Value::UInt(u)) | (Value::UInt(u), Value::Enum(e)) => {
1257 if e.value < 0 {
1258 false
1259 } else {
1260 e.value as u64 == *u
1261 }
1262 }
1263 (Value::Enum(e), Value::Double(d)) | (Value::Double(d), Value::Enum(e)) => {
1264 if d.is_nan() {
1265 return false;
1266 }
1267 let e_f64 = e.value as f64;
1268 e_f64 == *d && e_f64 as i32 == e.value
1269 }
1270 _ => false,
1271 }
1272 }
1273}
1274
1275impl Value {
1278 pub fn compare(&self, other: &Value) -> Option<Ordering> {
1283 match (self, other) {
1284 (Value::Bool(a), Value::Bool(b)) => Some(a.cmp(b)),
1285 (Value::Int(a), Value::Int(b)) => Some(a.cmp(b)),
1286 (Value::UInt(a), Value::UInt(b)) => Some(a.cmp(b)),
1287 (Value::Double(a), Value::Double(b)) => a.partial_cmp(b),
1288 (Value::String(a), Value::String(b)) => Some(a.cmp(b)),
1289 (Value::Bytes(a), Value::Bytes(b)) => Some(a.cmp(b)),
1290 (Value::Timestamp(a), Value::Timestamp(b)) => {
1291 Some((a.seconds, a.nanos).cmp(&(b.seconds, b.nanos)))
1292 }
1293 (Value::Duration(a), Value::Duration(b)) => {
1294 Some((a.seconds, a.nanos).cmp(&(b.seconds, b.nanos)))
1295 }
1296 (Value::Int(a), Value::UInt(b)) => {
1298 if *a < 0 {
1299 Some(Ordering::Less)
1300 } else {
1301 (*a as u64).partial_cmp(b)
1302 }
1303 }
1304 (Value::UInt(a), Value::Int(b)) => {
1305 if *b < 0 {
1306 Some(Ordering::Greater)
1307 } else {
1308 a.partial_cmp(&(*b as u64))
1309 }
1310 }
1311 (Value::Int(a), Value::Double(b)) => (*a as f64).partial_cmp(b),
1312 (Value::Double(a), Value::Int(b)) => a.partial_cmp(&(*b as f64)),
1313 (Value::UInt(a), Value::Double(b)) => (*a as f64).partial_cmp(b),
1314 (Value::Double(a), Value::UInt(b)) => a.partial_cmp(&(*b as f64)),
1315 (Value::Enum(e), Value::Int(i)) => (e.value as i64).partial_cmp(i),
1317 (Value::Int(i), Value::Enum(e)) => i.partial_cmp(&(e.value as i64)),
1318 (Value::Enum(e), Value::UInt(u)) => {
1319 if e.value < 0 {
1320 Some(Ordering::Less)
1321 } else {
1322 (e.value as u64).partial_cmp(u)
1323 }
1324 }
1325 (Value::UInt(u), Value::Enum(e)) => {
1326 if e.value < 0 {
1327 Some(Ordering::Greater)
1328 } else {
1329 u.partial_cmp(&(e.value as u64))
1330 }
1331 }
1332 (Value::Enum(e), Value::Double(d)) => (e.value as f64).partial_cmp(d),
1333 (Value::Double(d), Value::Enum(e)) => d.partial_cmp(&(e.value as f64)),
1334 _ => None,
1335 }
1336 }
1337}
1338
1339impl fmt::Display for Value {
1342 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1343 match self {
1344 Value::Null => write!(f, "null"),
1345 Value::Bool(v) => write!(f, "{}", v),
1346 Value::Int(v) => write!(f, "{}", v),
1347 Value::UInt(v) => write!(f, "{}u", v),
1348 Value::Double(v) => {
1349 if v.is_nan() {
1350 write!(f, "NaN")
1351 } else if v.is_infinite() {
1352 if v.is_sign_positive() {
1353 write!(f, "+infinity")
1354 } else {
1355 write!(f, "-infinity")
1356 }
1357 } else if v.fract() == 0.0 {
1358 write!(f, "{}.0", v)
1359 } else {
1360 write!(f, "{}", v)
1361 }
1362 }
1363 Value::String(v) => write!(f, "\"{}\"", v),
1364 Value::Bytes(v) => write!(f, "b\"{}\"", String::from_utf8_lossy(v)),
1365 Value::List(v) => {
1366 write!(f, "[")?;
1367 for (i, elem) in v.iter().enumerate() {
1368 if i > 0 {
1369 write!(f, ", ")?;
1370 }
1371 write!(f, "{}", elem)?;
1372 }
1373 write!(f, "]")
1374 }
1375 Value::Map(m) => {
1376 write!(f, "{{")?;
1377 for (i, (key, value)) in m.iter().enumerate() {
1378 if i > 0 {
1379 write!(f, ", ")?;
1380 }
1381 write!(f, "{}: {}", key.to_value(), value)?;
1382 }
1383 write!(f, "}}")
1384 }
1385 Value::Timestamp(t) => write!(f, "timestamp({})", t.seconds),
1386 Value::Duration(d) => write!(f, "duration({}s)", d.seconds),
1387 Value::Type(t) => write!(f, "type({})", t.name),
1388 Value::Optional(o) => match o {
1389 OptionalValue::None => write!(f, "optional.none()"),
1390 OptionalValue::Some(v) => write!(f, "optional.of({})", v),
1391 },
1392 Value::Message(m) => write!(f, "{}{{...}}", m.type_name()),
1393 Value::Enum(e) => write!(f, "{}({})", e.type_name, e.value),
1394 Value::Error(e) => write!(f, "error({})", e),
1395 }
1396 }
1397}
1398
1399#[cfg(test)]
1400mod tests {
1401 use super::*;
1402
1403 #[test]
1404 fn test_value_equality() {
1405 assert_eq!(Value::Int(42), Value::Int(42));
1406 assert_ne!(Value::Int(42), Value::Int(43));
1407 assert_eq!(Value::Int(42), Value::UInt(42));
1409 assert_ne!(Value::Int(-1), Value::UInt(1));
1410 let hello: Value = "hello".into();
1411 assert_eq!(hello, "hello".into());
1412 }
1413
1414 #[test]
1415 fn test_value_comparison() {
1416 assert_eq!(Value::Int(1).compare(&Value::Int(2)), Some(Ordering::Less));
1417 assert_eq!(
1418 Value::Int(2).compare(&Value::Int(1)),
1419 Some(Ordering::Greater)
1420 );
1421 assert_eq!(Value::Int(1).compare(&Value::Int(1)), Some(Ordering::Equal));
1422
1423 assert_eq!(
1425 Value::Int(-1).compare(&Value::UInt(1)),
1426 Some(Ordering::Less)
1427 );
1428 assert_eq!(
1429 Value::Int(1).compare(&Value::Double(1.5)),
1430 Some(Ordering::Less)
1431 );
1432 }
1433
1434 #[test]
1435 fn test_map_operations() {
1436 let mut map = ValueMap::new();
1437 map.insert(MapKey::String(Arc::from("key")), Value::Int(42));
1438
1439 assert_eq!(map.len(), 1);
1440 assert_eq!(
1441 map.get(&MapKey::String(Arc::from("key"))),
1442 Some(&Value::Int(42))
1443 );
1444 assert!(map.contains_key(&MapKey::String(Arc::from("key"))));
1445 assert!(!map.contains_key(&MapKey::String(Arc::from("other"))));
1446 }
1447
1448 #[test]
1449 fn test_map_key_from() {
1450 let key: MapKey = "hello".into();
1452 assert_eq!(key, MapKey::String(Arc::from("hello")));
1453
1454 let key: MapKey = String::from("world").into();
1456 assert_eq!(key, MapKey::String(Arc::from("world")));
1457
1458 let key: MapKey = 42i64.into();
1460 assert_eq!(key, MapKey::Int(42));
1461
1462 let key: MapKey = 42u64.into();
1464 assert_eq!(key, MapKey::UInt(42));
1465
1466 let key: MapKey = true.into();
1468 assert_eq!(key, MapKey::Bool(true));
1469 }
1470
1471 #[test]
1472 fn test_value_map_ergonomic() {
1473 let map = Value::map([("a", "1"), ("b", "2")]);
1475 if let Value::Map(m) = &map {
1476 assert_eq!(m.len(), 2);
1477 assert_eq!(
1478 m.get(&MapKey::String(Arc::from("a"))),
1479 Some(&Value::String(Arc::from("1")))
1480 );
1481 } else {
1482 panic!("expected map");
1483 }
1484
1485 let map = Value::map([(1i64, "one"), (2i64, "two")]);
1487 if let Value::Map(m) = &map {
1488 assert_eq!(
1489 m.get(&MapKey::Int(1)),
1490 Some(&Value::String(Arc::from("one")))
1491 );
1492 } else {
1493 panic!("expected map");
1494 }
1495
1496 let map = Value::map([("name", Value::from("Alice")), ("age", Value::from(30i64))]);
1498 if let Value::Map(m) = &map {
1499 assert_eq!(m.len(), 2);
1500 } else {
1501 panic!("expected map");
1502 }
1503 }
1504
1505 #[test]
1506 fn test_optional_value() {
1507 let none = OptionalValue::none();
1508 assert!(!none.is_present());
1509 assert!(none.as_value().is_none());
1510
1511 let some = OptionalValue::some(Value::Int(42));
1512 assert!(some.is_present());
1513 assert_eq!(some.as_value(), Some(&Value::Int(42)));
1514 }
1515
1516 #[test]
1517 fn test_timestamp_comparison() {
1518 let t1 = Timestamp::new(100, 0);
1519 let t2 = Timestamp::new(200, 0);
1520 let t3 = Timestamp::new(100, 500);
1521
1522 assert!(t1.is_before(&t2));
1523 assert!(t2.is_after(&t1));
1524 assert!(t1.is_before(&t3));
1525 }
1526
1527 #[test]
1528 fn test_duration_nanos() {
1529 let d = Duration::from_nanos(1_500_000_000);
1530 assert_eq!(d.seconds, 1);
1531 assert_eq!(d.nanos, 500_000_000);
1532 assert_eq!(d.to_nanos(), 1_500_000_000);
1533 }
1534
1535 #[test]
1536 fn test_cel_type() {
1537 assert_eq!(Value::Int(42).cel_type(), CelType::Int);
1538 let hello: Value = "hello".into();
1539 assert_eq!(hello.cel_type(), CelType::String);
1540 let list: Value = vec![Value::Int(1)].into();
1541 assert_eq!(list.cel_type(), CelType::list(CelType::Dyn));
1542 }
1543
1544 #[test]
1545 fn test_display() {
1546 assert_eq!(format!("{}", Value::Null), "null");
1547 assert_eq!(format!("{}", Value::Int(42)), "42");
1548 assert_eq!(format!("{}", Value::UInt(42)), "42u");
1549 let hello: Value = "hello".into();
1550 assert_eq!(format!("{}", hello), "\"hello\"");
1551 assert_eq!(format!("{}", Value::Bool(true)), "true");
1552 }
1553
1554 #[test]
1555 #[allow(clippy::approx_constant)]
1556 fn test_from_primitives() {
1557 let v: Value = true.into();
1558 assert_eq!(v, Value::Bool(true));
1559
1560 let v: Value = 42i64.into();
1561 assert_eq!(v, Value::Int(42));
1562
1563 let v: Value = 42u64.into();
1564 assert_eq!(v, Value::UInt(42));
1565
1566 let v: Value = 3.14f64.into();
1567 assert_eq!(v, Value::Double(3.14));
1568
1569 let v: Value = "hello".into();
1570 assert_eq!(v, Value::String(Arc::from("hello")));
1571
1572 let v: Value = String::from("world").into();
1573 assert_eq!(v, Value::String(Arc::from("world")));
1574 }
1575
1576 #[test]
1577 fn test_from_collections() {
1578 let v: Value = vec![Value::Int(1), Value::Int(2)].into();
1579 assert!(matches!(v, Value::List(_)));
1580
1581 let v: Value = vec![1u8, 2, 3].into();
1582 assert!(matches!(v, Value::Bytes(_)));
1583 }
1584
1585 #[test]
1586 #[allow(clippy::approx_constant)]
1587 fn test_try_from_success() {
1588 let v = Value::Int(42);
1589 let i: i64 = (&v).try_into().unwrap();
1590 assert_eq!(i, 42);
1591
1592 let v: Value = "hello".into();
1593 let s: &str = (&v).try_into().unwrap();
1594 assert_eq!(s, "hello");
1595
1596 let v = Value::Bool(true);
1597 let b: bool = (&v).try_into().unwrap();
1598 assert!(b);
1599
1600 let v = Value::UInt(100);
1601 let u: u64 = (&v).try_into().unwrap();
1602 assert_eq!(u, 100);
1603
1604 let v = Value::Double(3.14);
1605 let d: f64 = (&v).try_into().unwrap();
1606 assert_eq!(d, 3.14);
1607 }
1608
1609 #[test]
1610 fn test_try_from_error() {
1611 let v: Value = "hello".into();
1612 let result: Result<i64, ValueError> = (&v).try_into();
1613 assert!(result.is_err());
1614 let err = result.unwrap_err();
1615 assert_eq!(err.expected, "int");
1616 assert_eq!(err.found, "string");
1617 }
1618
1619 #[test]
1620 fn test_cel_value_to_value() {
1621 use crate::types::CelValue;
1622
1623 let cv = CelValue::String("test".to_string());
1624 let v: Value = cv.into();
1625 let s: &str = (&v).try_into().unwrap();
1626 assert_eq!(s, "test");
1627
1628 let cv = CelValue::Int(42);
1629 let v: Value = cv.into();
1630 assert_eq!(v, Value::Int(42));
1631
1632 let cv = CelValue::Null;
1633 let v: Value = cv.into();
1634 assert_eq!(v, Value::Null);
1635 }
1636
1637 #[test]
1638 fn test_try_from_timestamp() {
1639 let v = Value::Timestamp(Timestamp::new(1234567890, 0));
1640 let t: Timestamp = (&v).try_into().unwrap();
1641 assert_eq!(t.seconds, 1234567890);
1642
1643 let v = Value::Timestamp(Timestamp::new(1234567890, 500));
1645 let t: Timestamp = v.try_into().unwrap();
1646 assert_eq!(t.nanos, 500);
1647
1648 let v: Value = "not a timestamp".into();
1649 let result: Result<Timestamp, ValueError> = (&v).try_into();
1650 assert!(result.is_err());
1651 let err = result.unwrap_err();
1652 assert_eq!(err.expected, "timestamp");
1653 assert_eq!(err.found, "string");
1654 }
1655
1656 #[test]
1657 fn test_try_from_duration() {
1658 let v = Value::Duration(Duration::new(60, 0));
1659 let d: Duration = (&v).try_into().unwrap();
1660 assert_eq!(d.seconds, 60);
1661
1662 let v = Value::Duration(Duration::new(120, 500));
1664 let d: Duration = v.try_into().unwrap();
1665 assert_eq!(d.seconds, 120);
1666 assert_eq!(d.nanos, 500);
1667
1668 let v = Value::Int(42);
1669 let result: Result<Duration, ValueError> = (&v).try_into();
1670 assert!(result.is_err());
1671 let err = result.unwrap_err();
1672 assert_eq!(err.expected, "duration");
1673 assert_eq!(err.found, "int");
1674 }
1675
1676 #[test]
1677 fn test_try_from_list() {
1678 let v: Value = vec![Value::Int(1), Value::Int(2)].into();
1679 let list: &[Value] = (&v).try_into().unwrap();
1680 assert_eq!(list.len(), 2);
1681 assert_eq!(list[0], Value::Int(1));
1682 assert_eq!(list[1], Value::Int(2));
1683
1684 let v: Value = "not a list".into();
1685 let result: Result<&[Value], ValueError> = (&v).try_into();
1686 assert!(result.is_err());
1687 let err = result.unwrap_err();
1688 assert_eq!(err.expected, "list");
1689 assert_eq!(err.found, "string");
1690 }
1691
1692 #[test]
1693 fn test_try_from_map() {
1694 let v = Value::map([(MapKey::String("key".into()), Value::Int(42))]);
1695 let map: &ValueMap = (&v).try_into().unwrap();
1696 assert_eq!(map.len(), 1);
1697 assert_eq!(
1698 map.get(&MapKey::String("key".into())),
1699 Some(&Value::Int(42))
1700 );
1701
1702 let v: Value = "not a map".into();
1703 let result: Result<&ValueMap, ValueError> = (&v).try_into();
1704 assert!(result.is_err());
1705 let err = result.unwrap_err();
1706 assert_eq!(err.expected, "map");
1707 assert_eq!(err.found, "string");
1708 }
1709
1710 #[test]
1711 fn test_try_from_optional() {
1712 let v = Value::optional_some(Value::Int(42));
1713 let opt: &OptionalValue = (&v).try_into().unwrap();
1714 assert!(opt.is_present());
1715 assert_eq!(opt.as_value(), Some(&Value::Int(42)));
1716
1717 let v = Value::optional_none();
1718 let opt: &OptionalValue = (&v).try_into().unwrap();
1719 assert!(!opt.is_present());
1720
1721 let v = Value::Int(42);
1722 let result: Result<&OptionalValue, ValueError> = (&v).try_into();
1723 assert!(result.is_err());
1724 let err = result.unwrap_err();
1725 assert_eq!(err.expected, "optional");
1726 assert_eq!(err.found, "int");
1727 }
1728
1729 #[test]
1730 fn test_try_from_eval_error() {
1731 let v = Value::error(EvalError::division_by_zero());
1732 let err: &EvalError = (&v).try_into().unwrap();
1733 assert_eq!(err.message, "division by zero");
1734
1735 let v = Value::Int(42);
1736 let result: Result<&EvalError, ValueError> = (&v).try_into();
1737 assert!(result.is_err());
1738 let err = result.unwrap_err();
1739 assert_eq!(err.expected, "error");
1740 assert_eq!(err.found, "int");
1741 }
1742
1743 #[test]
1744 fn test_from_integer_widening() {
1745 let v: Value = 42i8.into();
1747 assert_eq!(v, Value::Int(42));
1748
1749 let v: Value = 42i16.into();
1750 assert_eq!(v, Value::Int(42));
1751
1752 let v: Value = 42i32.into();
1753 assert_eq!(v, Value::Int(42));
1754
1755 let v: Value = (42isize).into();
1756 assert_eq!(v, Value::Int(42));
1757
1758 let v: Value = 42u8.into();
1760 assert_eq!(v, Value::UInt(42));
1761
1762 let v: Value = 42u16.into();
1763 assert_eq!(v, Value::UInt(42));
1764
1765 let v: Value = 42u32.into();
1766 assert_eq!(v, Value::UInt(42));
1767
1768 let v: Value = (42usize).into();
1769 assert_eq!(v, Value::UInt(42));
1770 }
1771
1772 #[test]
1773 fn test_map_key_from_i32_u32() {
1774 let key: MapKey = 42i32.into();
1776 assert_eq!(key, MapKey::Int(42));
1777
1778 let key: MapKey = 42u32.into();
1780 assert_eq!(key, MapKey::UInt(42));
1781 }
1782
1783 #[test]
1784 fn test_from_option() {
1785 let v: Value = Some(42).into();
1787 assert_eq!(v, Value::Int(42));
1788
1789 let v: Value = Some("hello").into();
1790 assert_eq!(v, Value::String(Arc::from("hello")));
1791
1792 let v: Value = None::<i32>.into();
1794 assert_eq!(v, Value::Null);
1795
1796 let v: Value = None::<String>.into();
1797 assert_eq!(v, Value::Null);
1798
1799 let v: Value = Some(Some(42)).into();
1801 assert_eq!(v, Value::Int(42));
1802 }
1803
1804 #[test]
1805 fn test_from_option_in_map() {
1806 let email: Option<String> = None;
1807 let name: Option<&str> = Some("Alice");
1808
1809 let user = Value::map([("email", Value::from(email)), ("name", Value::from(name))]);
1810
1811 if let Value::Map(m) = user {
1812 assert_eq!(m.get(&MapKey::from("email")), Some(&Value::Null));
1813 assert_eq!(
1814 m.get(&MapKey::from("name")),
1815 Some(&Value::String(Arc::from("Alice")))
1816 );
1817 } else {
1818 panic!("expected map");
1819 }
1820 }
1821
1822 #[test]
1823 fn test_enum_numeric_equality() {
1824 let enum_val = Value::Enum(EnumValue::new("test.MyEnum", 1));
1825
1826 assert_eq!(enum_val, Value::Int(1));
1828 assert_eq!(Value::Int(1), enum_val);
1829 assert_ne!(enum_val, Value::Int(2));
1830
1831 assert_eq!(enum_val, Value::UInt(1));
1833 assert_eq!(Value::UInt(1), enum_val);
1834
1835 let neg_enum = Value::Enum(EnumValue::new("test.MyEnum", -1));
1837 assert_ne!(neg_enum, Value::UInt(1));
1838
1839 assert_eq!(enum_val, Value::Double(1.0));
1841 assert_eq!(Value::Double(1.0), enum_val);
1842 assert_ne!(enum_val, Value::Double(1.5));
1843
1844 assert_ne!(Value::Double(f64::NAN), enum_val);
1846
1847 let list = Value::List(Arc::from(vec![Value::Enum(EnumValue::new(
1849 "test.MyEnum",
1850 1,
1851 ))]));
1852 if let Value::List(items) = &list {
1853 assert!(items.contains(&Value::Int(1)));
1854 }
1855 }
1856
1857 #[test]
1858 fn test_enum_numeric_comparison() {
1859 let enum_val = Value::Enum(EnumValue::new("test.MyEnum", 5));
1860
1861 assert_eq!(enum_val.compare(&Value::Int(3)), Some(Ordering::Greater));
1862 assert_eq!(enum_val.compare(&Value::Int(5)), Some(Ordering::Equal));
1863 assert_eq!(enum_val.compare(&Value::Int(10)), Some(Ordering::Less));
1864
1865 assert_eq!(enum_val.compare(&Value::UInt(3)), Some(Ordering::Greater));
1866 assert_eq!(enum_val.compare(&Value::Double(5.0)), Some(Ordering::Equal));
1867
1868 let neg_enum = Value::Enum(EnumValue::new("test.MyEnum", -1));
1870 assert_eq!(neg_enum.compare(&Value::UInt(0)), Some(Ordering::Less));
1871 }
1872
1873 #[test]
1874 fn test_value_from_option_cel_optional() {
1875 let v = Value::from_option(Some(42));
1877 assert!(matches!(v, Value::Optional(OptionalValue::Some(_))));
1878
1879 let v = Value::from_option(None::<i32>);
1880 assert!(matches!(v, Value::Optional(OptionalValue::None)));
1881 }
1882}