cel_cxx/values/mod.rs
1//! CEL Value Types and Operations
2//!
3//! This module provides the core value types used in CEL expressions, along with
4//! comprehensive conversion and manipulation utilities. It forms the foundation
5//! of the CEL type system, supporting both primitive and composite data types.
6//!
7//! # Value Type Hierarchy
8//!
9//! The CEL value system is built around several core types:
10//!
11//! ## Primitive Types
12//! - **Null**: Represents absent values (`null`)
13//! - **Bool**: Boolean values (`true`, `false`)
14//! - **Int**: 64-bit signed integers (`i64`)
15//! - **Uint**: 64-bit unsigned integers (`u64`)
16//! - **Double**: IEEE 754 double-precision floating point (`f64`)
17//! - **String**: UTF-8 encoded strings
18//! - **Bytes**: Arbitrary byte sequences
19//!
20//! ## Time Types
21//! - **Duration**: Protocol Buffers Duration type (represents time spans)
22//! - **Timestamp**: Protocol Buffers Timestamp type (represents points in time)
23//!
24//! ## Composite Types
25//! - **List**: Ordered collections of values (`Vec<Value>`)
26//! - **Map**: Key-value mappings (`HashMap<MapKey, Value>`)
27//! - **Struct**: Protocol Buffers message types (not yet implemented)
28//! - **Optional**: Wrapper for optional values
29//!
30//! ## Special Types
31//! - **Type**: Meta-type representing CEL types themselves
32//! - **Error**: Error values from failed operations
33//! - **Unknown**: Partially evaluated expressions (not yet implemented)
34//! - **Opaque**: Custom user-defined types
35//!
36//! # Type Conversion System
37//!
38//! The module provides a comprehensive type conversion system built on Generic
39//! Associated Types (GATs) for safe, zero-cost conversions between Rust and CEL types.
40//!
41//! ## Core Conversion Traits
42//!
43//! - [`TypedValue`]: Types that have a known CEL type
44//! - [`IntoValue`]: Convert Rust types to CEL values
45//! - [`FromValue`]: Convert CEL values to Rust types (with GATs)
46//! - [`IntoConstant`]: Convert to compile-time constants
47//!
48//! ## Map Key Conversion
49//!
50//! - [`TypedMapKey`]: Types that can be used as map keys
51//! - [`IntoMapKey`]: Convert to CEL map keys
52//! - [`FromMapKey`]: Convert from CEL map keys
53//!
54//! # Memory Management and Lifetimes
55//!
56//! The value system is designed for efficient memory usage:
57//! - **Zero-copy conversions** where possible (`&str` from `String` values)
58//! - **Controlled lifetime erasure** for safe reference handling
59//! - **Reference counting** for shared data structures
60//! - **Clone-on-write** semantics for expensive operations
61//!
62//! # Examples
63//!
64//! ## Basic Value Creation and Conversion
65//!
66//! ```rust
67//! use cel_cxx::{Value, IntoValue, FromValue};
68//!
69//! // Create values from Rust types
70//! let null_val = Value::Null;
71//! let bool_val = true.into_value();
72//! let int_val = 42i64.into_value();
73//! let string_val = "hello".into_value();
74//!
75//! // Convert back to Rust types
76//! let rust_bool: bool = bool_val.try_into()?;
77//! let rust_int: i64 = int_val.try_into()?;
78//! let rust_string: String = string_val.try_into()?;
79//! # Ok::<(), cel_cxx::Error>(())
80//! ```
81//!
82//! ## Working with Collections
83//!
84//! ```rust
85//! use cel_cxx::{Value, MapKey};
86//! use std::collections::HashMap;
87//!
88//! // Create a list
89//! let list = Value::List(vec![
90//! Value::Int(1),
91//! Value::Int(2),
92//! Value::Int(3),
93//! ]);
94//!
95//! // Create a map
96//! let mut map = HashMap::new();
97//! map.insert(MapKey::String("name".to_string().into()), Value::String("Alice".to_string().into()));
98//! map.insert(MapKey::String("age".to_string().into()), Value::Int(30));
99//! let map_val = Value::Map(map);
100//! ```
101//!
102//! ## Reference Conversions with Lifetimes
103//!
104//! ```rust
105//! use cel_cxx::{Value, FromValue};
106//!
107//! let string_val = Value::String("hello world".to_string().into());
108//!
109//! // Convert to borrowed string slice (zero-copy)
110//! let borrowed_str = <&str>::from_value(&string_val)?;
111//! assert_eq!(borrowed_str, "hello world");
112//!
113//! // The original value owns the data
114//! drop(string_val); // borrowed_str is no longer valid after this
115//! # Ok::<(), cel_cxx::Error>(())
116//! ```
117//!
118//! ## Custom Type Integration
119//!
120//! For custom opaque types, use the derive macro instead of manual implementation:
121//!
122//! ```rust
123//! use cel_cxx::{Opaque, IntoValue, FromValue};
124//!
125//! #[derive(Opaque, Debug, Clone, PartialEq)]
126//! #[cel_cxx(display)]
127//! struct UserId(u64);
128//!
129//! // All necessary traits (TypedValue, IntoValue, FromValue) are automatically implemented
130//!
131//! // Usage
132//! let user_id = UserId(12345);
133//! let value = user_id.into_value();
134//! let converted_back = UserId::from_value(&value)?;
135//! # Ok::<(), cel_cxx::Error>(())
136//! ```
137//!
138//! # Error Handling
139//!
140//! The module provides comprehensive error handling through:
141//! - [`FromValueError`]: Conversion failures from CEL values
142//! - [`FromMapKeyError`]: Map key conversion failures
143//! - Detailed error messages with type information
144//!
145//! ## Error Example
146//!
147//! ```rust
148//! use cel_cxx::{Value, FromValue, FromValueError};
149//!
150//! let string_val = Value::String("not a number".to_string().into());
151//! let result = i64::from_value(&string_val);
152//!
153//! match result {
154//! Ok(num) => println!("Converted: {}", num),
155//! Err(e) => {
156//! println!("{}", e);
157//! }
158//! }
159//! ```
160//!
161//! # Performance Characteristics
162//!
163//! - **Conversion overhead**: Minimal for primitive types, optimized for references
164//! - **Memory usage**: Efficient representation, shared ownership where beneficial
165//! - **Type checking**: Compile-time where possible, fast runtime checks otherwise
166//! - **Collection operations**: Optimized for common access patterns
167//!
168//! # Thread Safety
169//!
170//! All value types are thread-safe:
171//! - Values can be shared across threads (`Send + Sync`)
172//! - Reference counting handles concurrent access safely
173//! - Conversion operations are atomic where required
174
175mod display;
176mod impls;
177mod opaque;
178mod optional;
179mod traits;
180
181use crate::types::*;
182use crate::{Error, Kind};
183use std::collections::HashMap;
184
185pub use opaque::*;
186pub use optional::*;
187pub use traits::*;
188
189/// CEL string value type.
190pub type StringValue = arc_slice::ArcStr;
191
192/// CEL bytes value type.
193pub type BytesValue = arc_slice::ArcBytes;
194
195/// CEL duration type.
196pub type Duration = chrono::Duration;
197
198/// CEL timestamp type.
199pub type Timestamp = chrono::DateTime<chrono::Utc>;
200
201/// CEL list value type.
202pub type ListValue = Vec<Value>;
203
204/// CEL map value type.
205pub type MapValue = HashMap<MapKey, Value>;
206
207/// CEL opaque value type.
208pub type OpaqueValue = Box<dyn Opaque>;
209
210/// CEL optional value type.
211pub type OptionalValue = Optional<Value>;
212
213/// Main CEL value type.
214///
215/// `Value` is the core value type of the CEL expression system, supporting all data types
216/// defined by the CEL specification. Each variant corresponds to a CEL basic type or composite type.
217///
218/// # CEL Type Mapping
219///
220/// - `Null` → CEL null
221/// - `Bool` → CEL bool
222/// - `Int` → CEL int (64-bit signed integer)
223/// - `Uint` → CEL uint (64-bit unsigned integer)
224/// - `Double` → CEL double (64-bit floating point)
225/// - `String` → CEL string
226/// - `Bytes` → CEL bytes
227/// - `Duration` → CEL duration (Protocol Buffers Duration)
228/// - `Timestamp` → CEL timestamp (Protocol Buffers Timestamp)
229/// - `List` → CEL list
230/// - `Map` → CEL map
231/// - `Type` → CEL type (type value)
232/// - `Error` → CEL error
233/// - `Opaque` → Opaque custom types
234/// - `Optional` → Optional value type
235///
236/// # Examples
237///
238/// ```rust,no_run
239/// use cel_cxx::Value;
240///
241/// // Basic types
242/// let null_val = Value::Null;
243/// let bool_val = Value::Bool(true);
244/// let int_val = Value::Int(-42);
245/// let uint_val = Value::Uint(42u64);
246/// let double_val = Value::Double(3.14);
247/// let string_val = Value::String("hello".to_string().into());
248/// let bytes_val = Value::Bytes(vec![1, 2, 3].into());
249///
250/// // Time types
251/// let duration = Value::Duration(chrono::Duration::seconds(30));
252/// let timestamp = Value::Timestamp(chrono::Utc::now());
253///
254/// // Container types
255/// let list = Value::List(vec![Value::Int(1), Value::Int(2)]);
256/// ```
257#[derive(Clone, Debug, PartialEq, Default)]
258pub enum Value {
259 /// Null value
260 #[default]
261 Null,
262
263 /// Boolean value
264 Bool(bool),
265
266 /// Signed 64-bit integer
267 Int(i64),
268
269 /// Unsigned 64-bit integer
270 Uint(u64),
271
272 /// 64-bit floating point number
273 Double(f64),
274
275 /// UTF-8 string
276 String(StringValue),
277
278 /// Byte array
279 Bytes(BytesValue),
280
281 /// Struct (not yet implemented)
282 Struct(()),
283
284 /// Duration (Protocol Buffers Duration)
285 Duration(Duration),
286
287 /// Timestamp (Protocol Buffers Timestamp)
288 Timestamp(Timestamp),
289
290 /// List of values
291 List(ListValue),
292
293 /// Key-value map
294 Map(MapValue),
295
296 /// Unknown type (not yet implemented)
297 Unknown(()),
298
299 /// CEL type value
300 Type(ValueType),
301
302 /// Error value
303 Error(Error),
304
305 /// Opaque custom type
306 Opaque(OpaqueValue),
307
308 /// Optional value type
309 Optional(OptionalValue),
310}
311
312impl Value {
313 /// Returns the kind of this value.
314 ///
315 /// Returns the corresponding [`Kind`] enum for fast type checking.
316 ///
317 /// # Examples
318 ///
319 /// ```rust,no_run
320 /// use cel_cxx::{Value, Kind};
321 ///
322 /// let val = Value::String("hello".to_string().into());
323 /// assert_eq!(val.kind(), Kind::String);
324 ///
325 /// let val = Value::List(vec![]);
326 /// assert_eq!(val.kind(), Kind::List);
327 /// ```
328 pub fn kind(&self) -> Kind {
329 match &self {
330 Value::Null => Kind::Null,
331 Value::Bool(_) => Kind::Bool,
332 Value::Int(_i) => Kind::Int,
333 Value::Uint(_u) => Kind::Uint,
334 Value::Double(_d) => Kind::Double,
335 Value::String(_s) => Kind::String,
336 Value::Bytes(_b) => Kind::Bytes,
337 Value::Struct(_s) => Kind::Struct,
338 Value::Duration(_d) => Kind::Duration,
339 Value::Timestamp(_t) => Kind::Timestamp,
340 Value::List(_l) => Kind::List,
341 Value::Map(_m) => Kind::Map,
342 Value::Unknown(_u) => Kind::Unknown,
343 Value::Type(_t) => Kind::Type,
344 Value::Error(_e) => Kind::Error,
345 Value::Opaque(_) | Value::Optional(_) => Kind::Opaque,
346 }
347 }
348
349 /// Returns the concrete type of this value.
350 ///
351 /// Returns detailed [`ValueType`] information including generic parameters.
352 /// For container types (List, Map), infers element or key-value types.
353 ///
354 /// # Type Inference Rules
355 ///
356 /// - **List**: Returns specific `List<T>` if all elements have the same type; otherwise `List<dyn>`
357 /// - **Map**: Infers key and value types; uses `dyn` types if inconsistent
358 /// - **Optional**: Infers type from contained value; uses `Optional<dyn>` for empty values
359 ///
360 /// # Examples
361 ///
362 /// ```rust,no_run
363 /// use cel_cxx::{Value, ValueType, ListType};
364 ///
365 /// let val = Value::String("hello".to_string().into());
366 /// assert_eq!(val.value_type(), ValueType::String);
367 ///
368 /// // Homogeneous list
369 /// let list = Value::List(vec![Value::Int(1), Value::Int(2)]);
370 /// assert_eq!(list.value_type(), ValueType::List(ListType::new(ValueType::Int)));
371 ///
372 /// // Heterogeneous list
373 /// let mixed_list = Value::List(vec![Value::Int(1), Value::String("hello".to_string().into())]);
374 /// assert_eq!(mixed_list.value_type(), ValueType::List(ListType::new(ValueType::Dyn)));
375 /// ```
376 pub fn value_type(&self) -> ValueType {
377 match &self {
378 Value::Null => ValueType::Null,
379 Value::Bool(_) => ValueType::Bool,
380 Value::Int(_) => ValueType::Int,
381 Value::Uint(_) => ValueType::Uint,
382 Value::Double(_) => ValueType::Double,
383 Value::String(_) => ValueType::String,
384 Value::Bytes(_) => ValueType::Bytes,
385 Value::Struct(_s) => {
386 todo!()
387 }
388 Value::Duration(_) => ValueType::Duration,
389 Value::Timestamp(_) => ValueType::Timestamp,
390 Value::List(list) => {
391 let mut iter = list.iter();
392 if let Some(v) = iter.next() {
393 let elem_type = v.value_type();
394 if elem_type == ValueType::Dyn {
395 return ValueType::List(ListType::new(ValueType::Dyn));
396 }
397 for v in iter {
398 if v.value_type() != elem_type {
399 return ValueType::List(ListType::new(ValueType::Dyn));
400 }
401 }
402 return ValueType::List(ListType::new(elem_type));
403 }
404 ValueType::List(ListType::new(ValueType::Dyn))
405 }
406 Value::Map(m) => {
407 let mut iter = m.iter();
408 if let Some((k, v)) = iter.next() {
409 let mut key_type = Some(k.mapkey_type());
410 let mut val_type = v.value_type();
411 for (k, v) in iter {
412 if let Some(prev_key_type) = key_type.clone() {
413 if k.mapkey_type() != prev_key_type {
414 key_type = None;
415 }
416 }
417 if val_type != ValueType::Dyn && v.value_type() != val_type {
418 val_type = ValueType::Dyn;
419 }
420
421 if key_type.is_none() && val_type == ValueType::Dyn {
422 break;
423 }
424 }
425 ValueType::Map(MapType::new(key_type.unwrap_or(MapKeyType::Dyn), val_type))
426 } else {
427 ValueType::Map(MapType::new(MapKeyType::Dyn, ValueType::Dyn))
428 }
429 }
430 Value::Unknown(_u) => ValueType::Unknown,
431 Value::Opaque(o) => ValueType::Opaque(o.opaque_type()),
432 Value::Optional(opt) => {
433 if let Some(v) = opt.as_option() {
434 return ValueType::Optional(OptionalType::new(v.value_type()));
435 }
436 ValueType::Optional(OptionalType::new(ValueType::Dyn))
437 }
438 Value::Type(_t) => ValueType::Type(TypeType::new(None)),
439 Value::Error(_e) => ValueType::Error,
440 }
441 }
442
443 /// Returns true if this value is a null value.
444 pub fn is_null(&self) -> bool {
445 matches!(self, Value::Null)
446 }
447
448 /// Returns true if this value is a boolean value.
449 pub fn is_bool(&self) -> bool {
450 matches!(self, Value::Bool(_))
451 }
452
453 /// Returns true if this value is a signed integer value.
454 pub fn is_int(&self) -> bool {
455 matches!(self, Value::Int(_))
456 }
457
458 /// Returns true if this value is an unsigned integer value.
459 pub fn is_uint(&self) -> bool {
460 matches!(self, Value::Uint(_))
461 }
462
463 /// Returns true if this value is a double value.
464 pub fn is_double(&self) -> bool {
465 matches!(self, Value::Double(_))
466 }
467
468 /// Returns true if this value is a string value.
469 pub fn is_string(&self) -> bool {
470 matches!(self, Value::String(_))
471 }
472
473 /// Returns true if this value is a byte array value.
474 pub fn is_bytes(&self) -> bool {
475 matches!(self, Value::Bytes(_))
476 }
477
478 /// Returns true if this value is a struct value.
479 pub fn is_struct(&self) -> bool {
480 matches!(self, Value::Struct(_))
481 }
482
483 /// Returns true if this value is a duration value.
484 pub fn is_duration(&self) -> bool {
485 matches!(self, Value::Duration(_))
486 }
487
488 /// Returns true if this value is a timestamp value.
489 pub fn is_timestamp(&self) -> bool {
490 matches!(self, Value::Timestamp(_))
491 }
492
493 /// Returns true if this value is a list value.
494 pub fn is_list(&self) -> bool {
495 matches!(self, Value::List(_))
496 }
497
498 /// Returns true if this value is a map value.
499 pub fn is_map(&self) -> bool {
500 matches!(self, Value::Map(_))
501 }
502
503 /// Returns true if this value is an unknown value.
504 pub fn is_unknown(&self) -> bool {
505 matches!(self, Value::Unknown(_))
506 }
507
508 /// Returns true if this value is a type value.
509 pub fn is_type(&self) -> bool {
510 matches!(self, Value::Type(_))
511 }
512
513 /// Returns true if this value is an error value.
514 pub fn is_error(&self) -> bool {
515 matches!(self, Value::Error(_))
516 }
517
518 /// Returns true if this value is an opaque value.
519 pub fn is_opaque(&self) -> bool {
520 matches!(self, Value::Opaque(_))
521 }
522
523 /// Returns true if this value is an optional value.
524 pub fn is_optional(&self) -> bool {
525 matches!(self, Value::Optional(_))
526 }
527
528 /// Returns the boolean value if this value is a boolean value.
529 pub fn as_bool(&self) -> Option<&bool> {
530 match self {
531 Value::Bool(b) => Some(b),
532 _ => None,
533 }
534 }
535
536 /// Returns the signed integer value if this value is a signed integer value.
537 pub fn as_int(&self) -> Option<&i64> {
538 match self {
539 Value::Int(i) => Some(i),
540 _ => None,
541 }
542 }
543
544 /// Returns the unsigned integer value if this value is an unsigned integer value.
545 pub fn as_uint(&self) -> Option<&u64> {
546 match self {
547 Value::Uint(u) => Some(u),
548 _ => None,
549 }
550 }
551
552 /// Returns the double value if this value is a double value.
553 pub fn as_double(&self) -> Option<&f64> {
554 match self {
555 Value::Double(d) => Some(d),
556 _ => None,
557 }
558 }
559
560 /// Returns the string value if this value is a string value.
561 pub fn as_string(&self) -> Option<&StringValue> {
562 match self {
563 Value::String(s) => Some(s),
564 _ => None,
565 }
566 }
567
568 /// Returns the byte array value if this value is a byte array value.
569 pub fn as_bytes(&self) -> Option<&BytesValue> {
570 match self {
571 Value::Bytes(b) => Some(b),
572 _ => None,
573 }
574 }
575
576 /// Returns the struct value if this value is a struct value.
577 pub fn as_struct(&self) -> Option<&()> {
578 match self {
579 Value::Struct(s) => Some(s),
580 _ => None,
581 }
582 }
583
584 /// Returns the duration value if this value is a duration value.
585 pub fn as_duration(&self) -> Option<&Duration> {
586 match self {
587 Value::Duration(d) => Some(d),
588 _ => None,
589 }
590 }
591
592 /// Returns the timestamp value if this value is a timestamp value.
593 pub fn as_timestamp(&self) -> Option<&Timestamp> {
594 match self {
595 Value::Timestamp(t) => Some(t),
596 _ => None,
597 }
598 }
599
600 /// Returns the list value if this value is a list value.
601 pub fn as_list(&self) -> Option<&ListValue> {
602 match self {
603 Value::List(l) => Some(l),
604 _ => None,
605 }
606 }
607
608 /// Returns the map value if this value is a map value.
609 pub fn as_map(&self) -> Option<&MapValue> {
610 match self {
611 Value::Map(m) => Some(m),
612 _ => None,
613 }
614 }
615
616 /// Returns the unknown value if this value is an unknown value.
617 pub fn as_unknown(&self) -> Option<&()> {
618 match self {
619 Value::Unknown(u) => Some(u),
620 _ => None,
621 }
622 }
623
624 /// Returns the type value if this value is a type value.
625 pub fn as_type(&self) -> Option<&ValueType> {
626 match self {
627 Value::Type(t) => Some(t),
628 _ => None,
629 }
630 }
631
632 /// Returns the error value if this value is an error value.
633 pub fn as_error(&self) -> Option<&Error> {
634 match self {
635 Value::Error(e) => Some(e),
636 _ => None,
637 }
638 }
639
640 /// Returns the opaque value if this value is an opaque value.
641 pub fn as_opaque(&self) -> Option<&OpaqueValue> {
642 match self {
643 Value::Opaque(o) => Some(o),
644 _ => None,
645 }
646 }
647
648 /// Returns the optional value if this value is an optional value.
649 pub fn as_optional(&self) -> Option<&OptionalValue> {
650 match self {
651 Value::Optional(o) => Some(o),
652 _ => None,
653 }
654 }
655
656 /// Returns a mutable reference to the boolean value if this value is a boolean value.
657 pub fn as_bool_mut(&mut self) -> Option<&mut bool> {
658 match self {
659 Value::Bool(b) => Some(b),
660 _ => None,
661 }
662 }
663
664 /// Returns a mutable reference to the signed integer value if this value is a signed integer value.
665 pub fn as_int_mut(&mut self) -> Option<&mut i64> {
666 match self {
667 Value::Int(i) => Some(i),
668 _ => None,
669 }
670 }
671
672 /// Returns a mutable reference to the unsigned integer value if this value is an unsigned integer value.
673 pub fn as_uint_mut(&mut self) -> Option<&mut u64> {
674 match self {
675 Value::Uint(u) => Some(u),
676 _ => None,
677 }
678 }
679
680 /// Returns a mutable reference to the double value if this value is a double value.
681 pub fn as_double_mut(&mut self) -> Option<&mut f64> {
682 match self {
683 Value::Double(d) => Some(d),
684 _ => None,
685 }
686 }
687
688 /// Returns a mutable reference to the string value if this value is a string value.
689 pub fn as_string_mut(&mut self) -> Option<&mut StringValue> {
690 match self {
691 Value::String(s) => Some(s),
692 _ => None,
693 }
694 }
695
696 /// Returns a mutable reference to the byte array value if this value is a byte array value.
697 pub fn as_bytes_mut(&mut self) -> Option<&mut BytesValue> {
698 match self {
699 Value::Bytes(b) => Some(b),
700 _ => None,
701 }
702 }
703
704 /// Returns a mutable reference to the struct value if this value is a struct value.
705 pub fn as_struct_mut(&mut self) -> Option<&mut ()> {
706 match self {
707 Value::Struct(s) => Some(s),
708 _ => None,
709 }
710 }
711
712 /// Returns a mutable reference to the duration value if this value is a duration value.
713 pub fn as_duration_mut(&mut self) -> Option<&mut Duration> {
714 match self {
715 Value::Duration(d) => Some(d),
716 _ => None,
717 }
718 }
719
720 /// Returns a mutable reference to the timestamp value if this value is a timestamp value.
721 pub fn as_timestamp_mut(&mut self) -> Option<&mut Timestamp> {
722 match self {
723 Value::Timestamp(t) => Some(t),
724 _ => None,
725 }
726 }
727
728 /// Returns a mutable reference to the list value if this value is a list value.
729 pub fn as_list_mut(&mut self) -> Option<&mut ListValue> {
730 match self {
731 Value::List(l) => Some(l),
732 _ => None,
733 }
734 }
735
736 /// Returns a mutable reference to the map value if this value is a map value.
737 pub fn as_map_mut(&mut self) -> Option<&mut MapValue> {
738 match self {
739 Value::Map(m) => Some(m),
740 _ => None,
741 }
742 }
743
744 /// Returns a mutable reference to the unknown value if this value is an unknown value.
745 pub fn as_unknown_mut(&mut self) -> Option<&mut ()> {
746 match self {
747 Value::Unknown(u) => Some(u),
748 _ => None,
749 }
750 }
751
752 /// Returns a mutable reference to the type value if this value is a type value.
753 pub fn as_type_mut(&mut self) -> Option<&mut ValueType> {
754 match self {
755 Value::Type(t) => Some(t),
756 _ => None,
757 }
758 }
759
760 /// Returns a mutable reference to the error value if this value is an error value.
761 pub fn as_error_mut(&mut self) -> Option<&mut Error> {
762 match self {
763 Value::Error(e) => Some(e),
764 _ => None,
765 }
766 }
767
768 /// Returns a mutable reference to the opaque value if this value is an opaque value.
769 pub fn as_opaque_mut(&mut self) -> Option<&mut OpaqueValue> {
770 match self {
771 Value::Opaque(o) => Some(o),
772 _ => None,
773 }
774 }
775
776 /// Returns a mutable reference to the optional value if this value is an optional value.
777 pub fn as_optional_mut(&mut self) -> Option<&mut OptionalValue> {
778 match self {
779 Value::Optional(o) => Some(o),
780 _ => None,
781 }
782 }
783
784 /// Converts the value to a null value.
785 pub fn into_null(self) -> Option<()> {
786 match self {
787 Value::Null => Some(()),
788 _ => None,
789 }
790 }
791
792 /// Converts the value to a boolean value.
793 pub fn into_bool(self) -> Option<bool> {
794 match self {
795 Value::Bool(b) => Some(b),
796 _ => None,
797 }
798 }
799
800 /// Converts the value to a signed integer value.
801 pub fn into_int(self) -> Option<i64> {
802 match self {
803 Value::Int(i) => Some(i),
804 _ => None,
805 }
806 }
807
808 /// Converts the value to an unsigned integer value.
809 pub fn into_uint(self) -> Option<u64> {
810 match self {
811 Value::Uint(u) => Some(u),
812 _ => None,
813 }
814 }
815
816 /// Converts the value to a double value.
817 pub fn into_double(self) -> Option<f64> {
818 match self {
819 Value::Double(d) => Some(d),
820 _ => None,
821 }
822 }
823
824 /// Converts the value to a string value.
825 pub fn into_string(self) -> Option<StringValue> {
826 match self {
827 Value::String(s) => Some(s),
828 _ => None,
829 }
830 }
831
832 /// Converts the value to a byte array value.
833 pub fn into_bytes(self) -> Option<BytesValue> {
834 match self {
835 Value::Bytes(b) => Some(b),
836 _ => None,
837 }
838 }
839
840 /// Converts the value to a struct value.
841 pub fn into_struct(self) -> Option<()> {
842 match self {
843 Value::Struct(s) => Some(s),
844 _ => None,
845 }
846 }
847
848 /// Converts the value to a duration value.
849 pub fn into_duration(self) -> Option<Duration> {
850 match self {
851 Value::Duration(d) => Some(d),
852 _ => None,
853 }
854 }
855
856 /// Converts the value to a timestamp value.
857 pub fn into_timestamp(self) -> Option<Timestamp> {
858 match self {
859 Value::Timestamp(t) => Some(t),
860 _ => None,
861 }
862 }
863
864 /// Converts the value to a list value.
865 pub fn into_list(self) -> Option<ListValue> {
866 match self {
867 Value::List(l) => Some(l),
868 _ => None,
869 }
870 }
871
872 /// Converts the value to a map value.
873 pub fn into_map(self) -> Option<MapValue> {
874 match self {
875 Value::Map(m) => Some(m),
876 _ => None,
877 }
878 }
879
880 /// Converts the value to an unknown value.
881 pub fn into_unknown(self) -> Option<()> {
882 match self {
883 Value::Unknown(u) => Some(u),
884 _ => None,
885 }
886 }
887
888 /// Converts the value to a type value.
889 pub fn into_type(self) -> Option<ValueType> {
890 match self {
891 Value::Type(t) => Some(t),
892 _ => None,
893 }
894 }
895
896 /// Converts the value to an error value.
897 pub fn into_error(self) -> Option<Error> {
898 match self {
899 Value::Error(e) => Some(e),
900 _ => None,
901 }
902 }
903
904 /// Converts the value to an opaque value.
905 pub fn into_opaque(self) -> Option<OpaqueValue> {
906 match self {
907 Value::Opaque(o) => Some(o),
908 _ => None,
909 }
910 }
911
912 /// Converts the value to an optional value.
913 pub fn into_optional(self) -> Option<OptionalValue> {
914 match self {
915 Value::Optional(o) => Some(o),
916 _ => None,
917 }
918 }
919
920 /// Converts the value to a null value and panics if the value is not a null value.
921 pub fn unwrap_null(self) {
922 match self {
923 Value::Null => (),
924 _ => panic!("called `Value::unwrap_null()` on a non-null value: {self:?}",),
925 }
926 }
927
928 /// Converts the value to a boolean value and panics if the value is not a boolean value.
929 pub fn unwrap_bool(self) -> bool {
930 match self {
931 Value::Bool(b) => b,
932 _ => panic!("called `Value::unwrap_bool()` on a non-bool value: {self:?}",),
933 }
934 }
935
936 /// Converts the value to a signed integer value and panics if the value is not a signed integer value.
937 pub fn unwrap_int(self) -> i64 {
938 match self {
939 Value::Int(i) => i,
940 _ => panic!("called `Value::unwrap_int()` on a non-int value: {self:?}",),
941 }
942 }
943
944 /// Converts the value to an unsigned integer value and panics if the value is not an unsigned integer value.
945 pub fn unwrap_uint(self) -> u64 {
946 match self {
947 Value::Uint(u) => u,
948 _ => panic!("called `Value::unwrap_uint()` on a non-uint value: {self:?}",),
949 }
950 }
951
952 /// Converts the value to a double value and panics if the value is not a double value.
953 pub fn unwrap_double(self) -> f64 {
954 match self {
955 Value::Double(d) => d,
956 _ => panic!("called `Value::unwrap_double()` on a non-double value: {self:?}",),
957 }
958 }
959
960 /// Converts the value to a string value and panics if the value is not a string value.
961 pub fn unwrap_string(self) -> StringValue {
962 match self {
963 Value::String(s) => s,
964 _ => panic!("called `Value::unwrap_string()` on a non-string value: {self:?}",),
965 }
966 }
967
968 /// Converts the value to a byte array value and panics if the value is not a byte array value.
969 pub fn unwrap_bytes(self) -> BytesValue {
970 match self {
971 Value::Bytes(b) => b,
972 _ => panic!("called `Value::unwrap_bytes()` on a non-bytes value: {self:?}",),
973 }
974 }
975
976 /// Converts the value to a struct value and panics if the value is not a struct value.
977 pub fn unwrap_struct(self) {
978 match self {
979 Value::Struct(s) => s,
980 _ => panic!("called `Value::unwrap_struct()` on a non-struct value: {self:?}",),
981 }
982 }
983
984 /// Converts the value to a duration value and panics if the value is not a duration value.
985 pub fn unwrap_duration(self) -> Duration {
986 match self {
987 Value::Duration(d) => d,
988 _ => panic!("called `Value::unwrap_duration()` on a non-duration value: {self:?}",),
989 }
990 }
991
992 /// Converts the value to a timestamp value and panics if the value is not a timestamp value.
993 pub fn unwrap_timestamp(self) -> Timestamp {
994 match self {
995 Value::Timestamp(t) => t,
996 _ => panic!("called `Value::unwrap_timestamp()` on a non-timestamp value: {self:?}",),
997 }
998 }
999
1000 /// Converts the value to a list value and panics if the value is not a list value.
1001 pub fn unwrap_list(self) -> ListValue {
1002 match self {
1003 Value::List(l) => l,
1004 _ => panic!("called `Value::unwrap_list()` on a non-list value: {self:?}",),
1005 }
1006 }
1007
1008 /// Converts the value to a map value and panics if the value is not a map value.
1009 pub fn unwrap_map(self) -> MapValue {
1010 match self {
1011 Value::Map(m) => m,
1012 _ => panic!("called `Value::unwrap_map()` on a non-map value: {self:?}",),
1013 }
1014 }
1015
1016 /// Converts the value to an unknown value and panics if the value is not an unknown value.
1017 pub fn unwrap_unknown(self) {
1018 match self {
1019 Value::Unknown(u) => u,
1020 _ => panic!("called `Value::unwrap_unknown()` on a non-unknown value: {self:?}",),
1021 }
1022 }
1023
1024 /// Converts the value to a type value and panics if the value is not a type value.
1025 pub fn unwrap_type(self) -> ValueType {
1026 match self {
1027 Value::Type(t) => t,
1028 _ => panic!("called `Value::unwrap_type()` on a non-type value: {self:?}",),
1029 }
1030 }
1031
1032 /// Converts the value to an error value and panics if the value is not an error value.
1033 pub fn unwrap_error(self) -> Error {
1034 match self {
1035 Value::Error(e) => e,
1036 _ => panic!("called `Value::unwrap_error()` on a non-error value: {self:?}",),
1037 }
1038 }
1039
1040 /// Converts the value to an opaque value and panics if the value is not an opaque value.
1041 pub fn unwrap_opaque(self) -> OpaqueValue {
1042 match self {
1043 Value::Opaque(o) => o,
1044 _ => panic!("called `Value::unwrap_opaque()` on a non-opaque value: {self:?}",),
1045 }
1046 }
1047
1048 /// Converts the value to an optional value and panics if the value is not an optional value.
1049 pub fn unwrap_optional(self) -> OptionalValue {
1050 match self {
1051 Value::Optional(o) => o,
1052 _ => panic!("called `Value::unwrap_optional()` on a non-optional value: {self:?}",),
1053 }
1054 }
1055
1056 /// Converts the value to a null value and panics if the value is not a null value.
1057 pub fn expect_null(self, msg: &str) {
1058 match self {
1059 Value::Null => (),
1060 _ => panic!("{msg}: {self:?}"),
1061 }
1062 }
1063
1064 /// Converts the value to a boolean value and panics if the value is not a boolean value.
1065 pub fn expect_bool(self, msg: &str) -> bool {
1066 match self {
1067 Value::Bool(b) => b,
1068 _ => panic!("{msg}: {self:?}"),
1069 }
1070 }
1071
1072 /// Converts the value to a signed integer value and panics if the value is not a signed integer value.
1073 pub fn expect_int(self, msg: &str) -> i64 {
1074 match self {
1075 Value::Int(i) => i,
1076 _ => panic!("{msg}: {self:?}"),
1077 }
1078 }
1079
1080 /// Converts the value to an unsigned integer value and panics if the value is not an unsigned integer value.
1081 pub fn expect_uint(self, msg: &str) -> u64 {
1082 match self {
1083 Value::Uint(u) => u,
1084 _ => panic!("{msg}: {self:?}"),
1085 }
1086 }
1087
1088 /// Converts the value to a double value and panics if the value is not a double value.
1089 pub fn expect_double(self, msg: &str) -> f64 {
1090 match self {
1091 Value::Double(d) => d,
1092 _ => panic!("{msg}: {self:?}"),
1093 }
1094 }
1095
1096 /// Converts the value to a string value and panics if the value is not a string value.
1097 pub fn expect_string(self, msg: &str) -> StringValue {
1098 match self {
1099 Value::String(s) => s,
1100 _ => panic!("{msg}: {self:?}"),
1101 }
1102 }
1103
1104 /// Converts the value to a byte array value and panics if the value is not a byte array value.
1105 pub fn expect_bytes(self, msg: &str) -> BytesValue {
1106 match self {
1107 Value::Bytes(b) => b,
1108 _ => panic!("{msg}: {self:?}"),
1109 }
1110 }
1111
1112 /// Converts the value to a struct value and panics if the value is not a struct value.
1113 pub fn expect_struct(self, msg: &str) {
1114 match self {
1115 Value::Struct(s) => s,
1116 _ => panic!("{msg}: {self:?}"),
1117 }
1118 }
1119
1120 /// Converts the value to a duration value and panics if the value is not a duration value.
1121 pub fn expect_duration(self, msg: &str) -> Duration {
1122 match self {
1123 Value::Duration(d) => d,
1124 _ => panic!("{msg}: {self:?}"),
1125 }
1126 }
1127
1128 /// Converts the value to a timestamp value and panics if the value is not a timestamp value.
1129 pub fn expect_timestamp(self, msg: &str) -> Timestamp {
1130 match self {
1131 Value::Timestamp(t) => t,
1132 _ => panic!("{msg}: {self:?}"),
1133 }
1134 }
1135
1136 /// Converts the value to a list value and panics if the value is not a list value.
1137 pub fn expect_list(self, msg: &str) -> ListValue {
1138 match self {
1139 Value::List(l) => l,
1140 _ => panic!("{msg}: {self:?}"),
1141 }
1142 }
1143
1144 /// Converts the value to a map value and panics if the value is not a map value.
1145 pub fn expect_map(self, msg: &str) -> MapValue {
1146 match self {
1147 Value::Map(m) => m,
1148 _ => panic!("{msg}: {self:?}"),
1149 }
1150 }
1151
1152 /// Converts the value to an unknown value and panics if the value is not an unknown value.
1153 pub fn expect_unknown(self, msg: &str) {
1154 match self {
1155 Value::Unknown(u) => u,
1156 _ => panic!("{msg}: {self:?}"),
1157 }
1158 }
1159
1160 /// Converts the value to a type value and panics if the value is not a type value.
1161 pub fn expect_type(self, msg: &str) -> ValueType {
1162 match self {
1163 Value::Type(t) => t,
1164 _ => panic!("{msg}: {self:?}"),
1165 }
1166 }
1167
1168 /// Converts the value to an error value and panics if the value is not an error value.
1169 pub fn expect_error(self, msg: &str) -> Error {
1170 match self {
1171 Value::Error(e) => e,
1172 _ => panic!("{msg}: {self:?}"),
1173 }
1174 }
1175
1176 /// Converts the value to an opaque value and panics if the value is not an opaque value.
1177 pub fn expect_opaque(self, msg: &str) -> OpaqueValue {
1178 match self {
1179 Value::Opaque(o) => o,
1180 _ => panic!("{msg}: {self:?}"),
1181 }
1182 }
1183
1184 /// Converts the value to an optional value and panics if the value is not an optional value.
1185 pub fn expect_optional(self, msg: &str) -> OptionalValue {
1186 match self {
1187 Value::Optional(o) => o,
1188 _ => panic!("{msg}: {self:?}"),
1189 }
1190 }
1191}
1192
1193impl From<MapKey> for Value {
1194 fn from(key: MapKey) -> Self {
1195 match key {
1196 MapKey::Bool(b) => Value::Bool(b),
1197 MapKey::Int(i) => Value::Int(i),
1198 MapKey::Uint(u) => Value::Uint(u),
1199 MapKey::String(s) => Value::String(s),
1200 }
1201 }
1202}
1203
1204impl TryFrom<Value> for MapKey {
1205 type Error = FromValueError;
1206
1207 fn try_from(value: Value) -> Result<Self, Self::Error> {
1208 match value {
1209 Value::Bool(b) => Ok(MapKey::Bool(b)),
1210 Value::Int(i) => Ok(MapKey::Int(i)),
1211 Value::Uint(u) => Ok(MapKey::Uint(u)),
1212 Value::String(s) => Ok(MapKey::String(s)),
1213 _ => Err(FromValueError::new(value, "MapKey")),
1214 }
1215 }
1216}
1217
1218/// CEL map key type.
1219///
1220/// `MapKey` represents value types that can be used as CEL map keys. According to the CEL
1221/// specification, only basic comparable types can be used as map keys.
1222///
1223/// # Supported Key Types
1224///
1225/// - `Bool`: Boolean keys
1226/// - `Int`: Signed integer keys
1227/// - `Uint`: Unsigned integer keys
1228/// - `String`: String keys
1229///
1230/// # Examples
1231///
1232/// ```rust,no_run
1233/// use cel_cxx::{MapKey, Value};
1234/// use std::collections::HashMap;
1235///
1236/// let mut map = HashMap::new();
1237///
1238/// // Different types of keys
1239/// map.insert(MapKey::String("name".to_string().into()), Value::String("Alice".to_string().into()));
1240/// map.insert(MapKey::Int(42), Value::String("answer".to_string().into()));
1241/// map.insert(MapKey::Bool(true), Value::String("yes".to_string().into()));
1242///
1243/// let map_value = Value::Map(map);
1244/// ```
1245#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1246pub enum MapKey {
1247 /// Boolean key
1248 Bool(bool),
1249 /// Signed integer key
1250 Int(i64),
1251 /// Unsigned integer key
1252 Uint(u64),
1253 /// String key
1254 String(StringValue),
1255}
1256
1257impl MapKey {
1258 /// Returns the kind of this map key.
1259 ///
1260 /// Returns the corresponding [`Kind`] enum.
1261 pub fn kind(&self) -> Kind {
1262 match self {
1263 MapKey::Bool(_) => Kind::Bool,
1264 MapKey::Int(_) => Kind::Int,
1265 MapKey::Uint(_) => Kind::Uint,
1266 MapKey::String(_) => Kind::String,
1267 }
1268 }
1269
1270 /// Returns the type of this map key.
1271 ///
1272 /// Returns the corresponding [`MapKeyType`] enum.
1273 pub fn mapkey_type(&self) -> MapKeyType {
1274 match self {
1275 MapKey::Bool(_) => MapKeyType::Bool,
1276 MapKey::Int(_) => MapKeyType::Int,
1277 MapKey::Uint(_) => MapKeyType::Uint,
1278 MapKey::String(_) => MapKeyType::String,
1279 }
1280 }
1281
1282 /// Creates a map key from a CEL value.
1283 ///
1284 /// Attempts to convert a [`Value`] to [`MapKey`]. Only supported basic types
1285 /// can be converted successfully.
1286 ///
1287 /// # Parameters
1288 ///
1289 /// - `value`: The CEL value to convert
1290 ///
1291 /// # Returns
1292 ///
1293 /// - `Ok(MapKey)`: Conversion successful
1294 /// - `Err(Value)`: Conversion failed, returns original value
1295 ///
1296 /// # Examples
1297 ///
1298 /// ```rust,no_run
1299 /// use cel_cxx::{Value, MapKey};
1300 ///
1301 /// // Successful conversion
1302 /// let key = MapKey::from_value(Value::String("key".to_string().into())).unwrap();
1303 /// assert_eq!(key, MapKey::String("key".to_string().into()));
1304 ///
1305 /// // Failed conversion
1306 /// let result = MapKey::from_value(Value::List(vec![]));
1307 /// assert!(result.is_err());
1308 /// ```
1309 pub fn from_value(value: Value) -> Result<Self, Value> {
1310 match value {
1311 Value::Bool(b) => Ok(MapKey::Bool(b)),
1312 Value::Int(i) => Ok(MapKey::Int(i)),
1313 Value::Uint(u) => Ok(MapKey::Uint(u)),
1314 Value::String(s) => Ok(MapKey::String(s)),
1315 _ => Err(value),
1316 }
1317 }
1318
1319 /// Converts this map key to a CEL value.
1320 ///
1321 /// Converts [`MapKey`] to the corresponding [`Value`].
1322 ///
1323 /// # Examples
1324 ///
1325 /// ```rust,no_run
1326 /// use cel_cxx::{MapKey, Value};
1327 ///
1328 /// let key = MapKey::String("hello".to_string().into());
1329 /// let value = key.into_value();
1330 /// assert_eq!(value, Value::String("hello".to_string().into()));
1331 /// ```
1332 pub fn into_value(self) -> Value {
1333 match self {
1334 MapKey::Bool(b) => Value::Bool(b),
1335 MapKey::Int(i) => Value::Int(i),
1336 MapKey::Uint(u) => Value::Uint(u),
1337 MapKey::String(s) => Value::String(s),
1338 }
1339 }
1340}
1341
1342/// CEL constant value.
1343///
1344/// `Constant` represents constant values known at compile time, supporting CEL's basic data types.
1345/// Constants can be used for compile-time optimization and type inference.
1346///
1347/// # Supported Types
1348///
1349/// - `Null`: Null value
1350/// - `Bool`: Boolean value
1351/// - `Int`: 64-bit signed integer
1352/// - `Uint`: 64-bit unsigned integer
1353/// - `Double`: 64-bit floating point number
1354/// - `String`: UTF-8 string
1355/// - `Bytes`: Byte array
1356/// - `Duration`: Time duration
1357/// - `Timestamp`: Timestamp
1358///
1359/// # Examples
1360///
1361/// ```rust,no_run
1362/// use cel_cxx::Constant;
1363///
1364/// let null_const = Constant::Null;
1365/// let bool_const = Constant::Bool(true);
1366/// let int_const = Constant::Int(42);
1367/// let string_const = Constant::String("hello".to_string().into());
1368/// ```
1369#[derive(Debug, Clone, Default, PartialEq)]
1370pub enum Constant {
1371 /// Null constant
1372 #[default]
1373 Null,
1374 /// Boolean constant
1375 Bool(bool),
1376 /// Signed integer constant
1377 Int(i64),
1378 /// Unsigned integer constant
1379 Uint(u64),
1380 /// Floating point constant
1381 Double(f64),
1382 /// Byte array constant
1383 Bytes(BytesValue),
1384 /// String constant
1385 String(StringValue),
1386 /// Duration constant
1387 Duration(chrono::Duration),
1388 /// Timestamp constant
1389 Timestamp(chrono::DateTime<chrono::Utc>),
1390}
1391
1392impl Constant {
1393 /// Returns the type of the constant.
1394 ///
1395 /// Returns the CEL type corresponding to the constant value.
1396 pub fn value_type(&self) -> ValueType {
1397 match self {
1398 Self::Null => ValueType::Null,
1399 Self::Bool(_) => ValueType::Bool,
1400 Self::Int(_) => ValueType::Int,
1401 Self::Uint(_) => ValueType::Uint,
1402 Self::Double(_) => ValueType::Double,
1403 Self::Bytes(_) => ValueType::Bytes,
1404 Self::String(_) => ValueType::String,
1405 Self::Duration(_) => ValueType::Duration,
1406 Self::Timestamp(_) => ValueType::Timestamp,
1407 }
1408 }
1409
1410 /// Converts the constant to a CEL value.
1411 ///
1412 /// Converts the constant to the corresponding [`Value`] type.
1413 ///
1414 /// [`Value`]: crate::Value
1415 pub fn value(&self) -> Value {
1416 match self {
1417 Self::Null => Value::Null,
1418 Self::Bool(value) => Value::Bool(*value),
1419 Self::Int(value) => Value::Int(*value),
1420 Self::Uint(value) => Value::Uint(*value),
1421 Self::Double(value) => Value::Double(*value),
1422 Self::Bytes(value) => Value::Bytes(value.clone()),
1423 Self::String(value) => Value::String(value.clone()),
1424 Self::Duration(value) => Value::Duration(*value),
1425 Self::Timestamp(value) => Value::Timestamp(*value),
1426 }
1427 }
1428}
1429
1430impl TryFrom<Value> for Constant {
1431 type Error = FromValueError;
1432
1433 fn try_from(value: Value) -> Result<Self, Self::Error> {
1434 match value {
1435 Value::Null => Ok(Constant::Null),
1436 Value::Bool(b) => Ok(Constant::Bool(b)),
1437 Value::Int(i) => Ok(Constant::Int(i)),
1438 Value::Uint(u) => Ok(Constant::Uint(u)),
1439 Value::Double(d) => Ok(Constant::Double(d)),
1440 Value::Bytes(b) => Ok(Constant::Bytes(b)),
1441 Value::String(s) => Ok(Constant::String(s)),
1442 Value::Duration(d) => Ok(Constant::Duration(d)),
1443 Value::Timestamp(t) => Ok(Constant::Timestamp(t)),
1444 _ => Err(FromValueError::new(value, "Constant")),
1445 }
1446 }
1447}
1448
1449#[cfg(test)]
1450mod test {
1451 use super::*;
1452
1453 #[test]
1454 fn test_value_kind() {
1455 let cases = vec![
1456 (Value::Null, Kind::Null),
1457 (Value::Bool(true), Kind::Bool),
1458 (Value::Int(1), Kind::Int),
1459 (Value::Uint(1), Kind::Uint),
1460 (Value::Double(1.0), Kind::Double),
1461 (Value::String("test".into()), Kind::String),
1462 (Value::Bytes(b"abc".into()), Kind::Bytes),
1463 (
1464 Value::Duration(chrono::Duration::seconds(1)),
1465 Kind::Duration,
1466 ),
1467 (Value::Timestamp(chrono::Utc::now()), Kind::Timestamp),
1468 (Value::List(vec![]), Kind::List),
1469 (Value::Map(HashMap::new()), Kind::Map),
1470 (Value::Type(ValueType::Null), Kind::Type),
1471 (
1472 Value::Error(Error::invalid_argument("invalid")),
1473 Kind::Error,
1474 ),
1475 (Value::Optional(Optional::none()), Kind::Opaque),
1476 ];
1477
1478 for (value, expected_kind) in cases {
1479 assert_eq!(value.kind(), expected_kind);
1480 }
1481 }
1482
1483 #[test]
1484 fn test_key_kind() {
1485 let cases = vec![
1486 (MapKey::Bool(true), Kind::Bool),
1487 (MapKey::Int(1), Kind::Int),
1488 (MapKey::Uint(1), Kind::Uint),
1489 (MapKey::String("test".into()), Kind::String),
1490 ];
1491
1492 for (key, expected_kind) in cases {
1493 assert_eq!(key.kind(), expected_kind);
1494 }
1495 }
1496
1497 #[test]
1498 fn test_value_type() {
1499 let cases = vec![
1500 (Value::Null, ValueType::Null),
1501 (Value::Bool(true), ValueType::Bool),
1502 (Value::Int(1), ValueType::Int),
1503 (Value::Uint(1), ValueType::Uint),
1504 (Value::Double(1.0), ValueType::Double),
1505 (Value::String("test".into()), ValueType::String),
1506 (Value::Bytes(b"abc".into()), ValueType::Bytes),
1507 (
1508 Value::Duration(chrono::Duration::seconds(1)),
1509 ValueType::Duration,
1510 ),
1511 (Value::Timestamp(chrono::Utc::now()), ValueType::Timestamp),
1512 (
1513 Value::List(vec![Value::Int(1), Value::Int(2), Value::Int(3)]),
1514 ValueType::List(ListType::new(ValueType::Int)),
1515 ),
1516 (
1517 Value::Map(HashMap::from([(
1518 MapKey::String("test".into()),
1519 Value::Int(1),
1520 )])),
1521 ValueType::Map(MapType::new(MapKeyType::String, ValueType::Int)),
1522 ),
1523 (
1524 Value::Type(ValueType::Double),
1525 ValueType::Type(TypeType::new(None)),
1526 ),
1527 (
1528 Value::Error(Error::invalid_argument("invalid")),
1529 ValueType::Error,
1530 ),
1531 (
1532 Value::Optional(Optional::new(Value::Int(5))),
1533 ValueType::Optional(OptionalType::new(ValueType::Int)),
1534 ),
1535 ];
1536
1537 for (i, (value, expected_type)) in cases.into_iter().enumerate() {
1538 assert_eq!(value.value_type(), expected_type, "case {i} failed");
1539 }
1540 }
1541}