Expand description
CEL Value Types and Operations
This module provides the core value types used in CEL expressions, along with comprehensive conversion and manipulation utilities. It forms the foundation of the CEL type system, supporting both primitive and composite data types.
§Value Type Hierarchy
The CEL value system is built around several core types:
§Primitive Types
- Null: Represents absent values (
null
) - Bool: Boolean values (
true
,false
) - Int: 64-bit signed integers (
i64
) - Uint: 64-bit unsigned integers (
u64
) - Double: IEEE 754 double-precision floating point (
f64
) - String: UTF-8 encoded strings
- Bytes: Arbitrary byte sequences
§Time Types
- Duration: Protocol Buffers Duration type (represents time spans)
- Timestamp: Protocol Buffers Timestamp type (represents points in time)
§Composite Types
- List: Ordered collections of values (
Vec<Value>
) - Map: Key-value mappings (
HashMap<MapKey, Value>
) - Struct: Protocol Buffers message types (not yet implemented)
- Optional: Wrapper for optional values
§Special Types
- Type: Meta-type representing CEL types themselves
- Error: Error values from failed operations
- Unknown: Partially evaluated expressions (not yet implemented)
- Opaque: Custom user-defined types
§Type Conversion System
The module provides a comprehensive type conversion system built on Generic Associated Types (GATs) for safe, zero-cost conversions between Rust and CEL types.
§Core Conversion Traits
TypedValue
: Types that have a known CEL typeIntoValue
: Convert Rust types to CEL valuesFromValue
: Convert CEL values to Rust types (with GATs)IntoConstant
: Convert to compile-time constants
§Map Key Conversion
TypedMapKey
: Types that can be used as map keysIntoMapKey
: Convert to CEL map keysFromMapKey
: Convert from CEL map keys
§Memory Management and Lifetimes
The value system is designed for efficient memory usage:
- Zero-copy conversions where possible (
&str
fromString
values) - Controlled lifetime erasure for safe reference handling
- Reference counting for shared data structures
- Clone-on-write semantics for expensive operations
§Examples
§Basic Value Creation and Conversion
use cel_cxx::{Value, IntoValue, FromValue};
// Create values from Rust types
let null_val = Value::Null;
let bool_val = true.into_value();
let int_val = 42i64.into_value();
let string_val = "hello".into_value();
// Convert back to Rust types
let rust_bool: bool = bool_val.try_into()?;
let rust_int: i64 = int_val.try_into()?;
let rust_string: String = string_val.try_into()?;
§Working with Collections
use cel_cxx::{Value, MapKey};
use std::collections::HashMap;
// Create a list
let list = Value::List(vec![
Value::Int(1),
Value::Int(2),
Value::Int(3),
]);
// Create a map
let mut map = HashMap::new();
map.insert(MapKey::String("name".to_string().into()), Value::String("Alice".to_string().into()));
map.insert(MapKey::String("age".to_string().into()), Value::Int(30));
let map_val = Value::Map(map);
§Reference Conversions with Lifetimes
use cel_cxx::{Value, FromValue};
let string_val = Value::String("hello world".to_string().into());
// Convert to borrowed string slice (zero-copy)
let borrowed_str = <&str>::from_value(&string_val)?;
assert_eq!(borrowed_str, "hello world");
// The original value owns the data
drop(string_val); // borrowed_str is no longer valid after this
§Custom Type Integration
For custom opaque types, use the derive macro instead of manual implementation:
use cel_cxx::{Opaque, IntoValue, FromValue};
#[derive(Opaque, Debug, Clone, PartialEq)]
struct UserId(u64);
impl std::fmt::Display for UserId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "User({})", self.0)
}
}
// All necessary traits (TypedValue, IntoValue, FromValue) are automatically implemented
// Usage
let user_id = UserId(12345);
let value = user_id.into_value();
let converted_back = UserId::from_value(&value)?;
§Error Handling
The module provides comprehensive error handling through:
FromValueError
: Conversion failures from CEL valuesFromMapKeyError
: Map key conversion failures- Detailed error messages with type information
§Error Example
use cel_cxx::{Value, FromValue, FromValueError};
let string_val = Value::String("not a number".to_string().into());
let result = i64::from_value(&string_val);
match result {
Ok(num) => println!("Converted: {}", num),
Err(e) => {
println!("{}", e);
}
}
§Performance Characteristics
- Conversion overhead: Minimal for primitive types, optimized for references
- Memory usage: Efficient representation, shared ownership where beneficial
- Type checking: Compile-time where possible, fast runtime checks otherwise
- Collection operations: Optimized for common access patterns
§Thread Safety
All value types are thread-safe:
- Values can be shared across threads (
Send + Sync
) - Reference counting handles concurrent access safely
- Conversion operations are atomic where required
Structs§
- From
MapKey Error - Error type for failed map key conversions.
- From
Value Error - Error type for failed value conversions.
- Optional
- CEL-compatible optional value type.
Enums§
Traits§
- From
MapKey - Trait for converting CEL map keys into Rust types.
- From
Value - Trait for converting CEL values into Rust types.
- Into
Constant - Trait for types that can be converted into compile-time CEL constants.
- Into
MapKey - Trait for converting values into CEL map keys.
- Into
Result - Trait for converting return values to CEL results.
- Into
Value - Trait for converting values into CEL values.
- Opaque
- Trait for opaque types that can be stored in CEL values.
- Typed
MapKey - Trait for types that can be used as map keys and have a known CEL map key type.
- Typed
Opaque - Trait for opaque types with additional type constraints.
- Typed
Value - Trait for types that have a known CEL type.
Type Aliases§
- Bytes
Value - CEL bytes value type.
- Duration
- CEL duration type.
- List
Value - CEL list value type.
- MapValue
- CEL map value type.
- Opaque
Value - CEL opaque value type.
- Optional
Value - CEL optional value type.
- String
Value - CEL string value type.
- Timestamp
- CEL timestamp type.