cel_cxx/types/mod.rs
1//! CEL type system types and type definitions.
2//!
3//! This module provides the core type system for CEL expressions, including
4//! the [`ValueType`] enum and type conversion utilities.
5//!
6//! This module provides the complete type system for CEL (Common Expression Language).
7//! It defines all the types that can be used in CEL expressions, from primitive types
8//! like integers and strings to complex types like lists, maps, and Protocol Buffer messages.
9//!
10//! # Type Hierarchy
11//!
12//! The CEL type system is built around the [`ValueType`] enum, which represents all
13//! possible types in CEL:
14//!
15//! ## Primitive Types
16//! - **`null`**: Represents the absence of a value
17//! - **`bool`**: Boolean values (`true`/`false`)
18//! - **`int`**: 64-bit signed integers
19//! - **`uint`**: 64-bit unsigned integers
20//! - **`double`**: Double-precision floating point numbers
21//! - **`string`**: UTF-8 encoded text
22//! - **`bytes`**: Byte arrays
23//!
24//! ## Time Types
25//! - **`duration`**: Time spans (from Protocol Buffers)
26//! - **`timestamp`**: Points in time (from Protocol Buffers)
27//!
28//! ## Collection Types
29//! - **`list<T>`**: Ordered sequences of values
30//! - **`map<K, V>`**: Key-value mappings
31//!
32//! ## Protocol Buffer Types
33//! - **`struct`**: Protocol Buffer messages
34//! - **Wrapper types**: `BoolValue`, `StringValue`, etc.
35//! - **`any`**: Can hold any Protocol Buffer message
36//! - **`enum`**: Protocol Buffer enumerations
37//!
38//! ## Advanced Types
39//! - **`type`**: Represents types themselves as values
40//! - **`function`**: Function signatures
41//! - **`optional<T>`**: Nullable values
42//! - **Opaque types**: Custom user-defined types
43//! - **Type parameters**: For generic type definitions
44//!
45//! # Examples
46//!
47//! ## Working with primitive types
48//!
49//! ```rust,no_run
50//! use cel_cxx::types::*;
51//! use cel_cxx::Kind;
52//!
53//! // Create primitive types
54//! let int_type = ValueType::Int;
55//! let string_type = ValueType::String;
56//! let bool_type = ValueType::Bool;
57//!
58//! // Check type kinds
59//! assert_eq!(int_type.kind(), Kind::Int);
60//! assert_eq!(string_type.kind(), Kind::String);
61//! assert_eq!(bool_type.kind(), Kind::Bool);
62//! ```
63//!
64//! ## Working with collection types
65//!
66//! ```rust,no_run
67//! use cel_cxx::types::*;
68//!
69//! // List of strings: list<string>
70//! let string_list = ValueType::List(ListType::new(ValueType::String));
71//!
72//! // Map from string to int: map<string, int>
73//! let string_to_int_map = ValueType::Map(MapType::new(
74//! MapKeyType::String,
75//! ValueType::Int
76//! ));
77//!
78//! // Nested types: list<map<string, int>>
79//! let nested_type = ValueType::List(ListType::new(string_to_int_map));
80//! ```
81//!
82//! ## Working with optional types
83//!
84//! ```rust,no_run
85//! use cel_cxx::types::*;
86//!
87//! // Optional string: optional<string>
88//! let optional_string = ValueType::Optional(OptionalType::new(ValueType::String));
89//!
90//! // Optional list: optional<list<int>>
91//! let optional_list = ValueType::Optional(OptionalType::new(
92//! ValueType::List(ListType::new(ValueType::Int))
93//! ));
94//! ```
95//!
96//! ## Working with function types
97//!
98//! ```rust,no_run
99//! use cel_cxx::types::*;
100//!
101//! // Function type: (string, int) -> bool
102//! let func_type = ValueType::Function(FunctionType::new(
103//! ValueType::Bool,
104//! vec![ValueType::String, ValueType::Int]
105//! ));
106//! ```
107
108use std::fmt::Debug;
109
110mod convert;
111mod display;
112use crate::values::TypedValue;
113use crate::Kind;
114
115pub use convert::InvalidMapKeyType;
116
117/// CEL type representation.
118///
119/// This enum represents all possible types in the CEL type system. CEL supports
120/// a rich type system including primitive types, complex types, and Protocol Buffer
121/// types. Each type corresponds to values that can be used in CEL expressions.
122///
123/// # Examples
124///
125/// ## Basic Type Usage
126///
127/// ```rust,no_run
128/// use cel_cxx::*;
129///
130/// // Create different types
131/// let int_type = ValueType::Int;
132/// let string_type = ValueType::String;
133/// let list_type = ValueType::List(ListType::new(ValueType::String));
134///
135/// // Check the kind of a type
136/// assert_eq!(int_type.kind(), Kind::Int);
137/// ```
138///
139/// ## Map Types
140///
141/// ```rust,no_run
142/// use cel_cxx::*;
143///
144/// let map_type = ValueType::Map(MapType::new(
145/// MapKeyType::String,
146/// ValueType::Int
147/// ));
148///
149/// assert_eq!(map_type.kind(), Kind::Map);
150/// ```
151#[derive(Clone, Debug, Hash, PartialEq, Eq)]
152pub enum ValueType {
153 /// Null type - represents the absence of a value.
154 ///
155 /// This corresponds to CEL's `null` literal.
156 Null,
157
158 /// Boolean type - represents true/false values.
159 ///
160 /// This corresponds to CEL's `bool` type and literals like `true` and `false`.
161 Bool,
162
163 /// Signed 64-bit integer type.
164 ///
165 /// This corresponds to CEL's `int` type and integer literals like `42`.
166 Int,
167
168 /// Unsigned 64-bit integer type.
169 ///
170 /// This corresponds to CEL's `uint` type and unsigned integer literals like `42u`.
171 Uint,
172
173 /// Double-precision floating point type.
174 ///
175 /// This corresponds to CEL's `double` type and floating-point literals like `3.14`.
176 Double,
177
178 /// String type.
179 ///
180 /// This corresponds to CEL's `string` type and string literals like `"hello"`.
181 String,
182
183 /// Byte array type.
184 ///
185 /// This corresponds to CEL's `bytes` type and byte literals like `b"hello"`.
186 Bytes,
187
188 /// Struct type for Protocol Buffer messages.
189 ///
190 /// This represents structured data types, typically Protocol Buffer messages.
191 Struct(StructType),
192
193 /// Duration type from Protocol Buffers.
194 ///
195 /// This corresponds to `google.protobuf.Duration` and duration literals like `duration("1h")`.
196 Duration,
197
198 /// Timestamp type from Protocol Buffers.
199 ///
200 /// This corresponds to `google.protobuf.Timestamp` and timestamp literals like `timestamp("2023-01-01T00:00:00Z")`.
201 Timestamp,
202
203 /// List type - represents ordered collections.
204 ///
205 /// This corresponds to CEL's list type and literals like `[1, 2, 3]`.
206 List(ListType),
207
208 /// Map type - represents key-value mappings.
209 ///
210 /// This corresponds to CEL's map type and literals like `{"key": "value"}`.
211 Map(MapType),
212
213 /// Unknown type - used for values that cannot be determined at compile time.
214 ///
215 /// This is typically used in error conditions or for dynamic values.
216 Unknown,
217
218 /// Type type - represents type values themselves.
219 ///
220 /// This corresponds to CEL's type system where types can be values, such as `int` or `string`.
221 Type(TypeType),
222
223 /// Error type - represents error values.
224 ///
225 /// This is used when evaluation results in an error condition.
226 Error,
227
228 /// Any type from Protocol Buffers.
229 ///
230 /// This corresponds to `google.protobuf.Any` which can hold any Protocol Buffer message.
231 Any,
232
233 /// Dynamic type - represents values whose type is determined at runtime.
234 ///
235 /// This is used for values that can be of any type.
236 Dyn,
237
238 /// Opaque types - user-defined types that are not directly CEL types.
239 ///
240 /// This allows integration of custom Rust types into CEL expressions.
241 Opaque(OpaqueType),
242
243 /// Optional type - represents values that may or may not be present.
244 ///
245 /// This corresponds to CEL's optional types and the `optional` type constructor.
246 Optional(OptionalType),
247
248 /// Boolean wrapper type from Protocol Buffers.
249 ///
250 /// This corresponds to `google.protobuf.BoolValue`.
251 BoolWrapper,
252
253 /// Integer wrapper type from Protocol Buffers.
254 ///
255 /// This corresponds to `google.protobuf.Int32Value`.
256 IntWrapper,
257
258 /// Unsigned integer wrapper type from Protocol Buffers.
259 ///
260 /// This corresponds to `google.protobuf.UInt32Value`.
261 UintWrapper,
262
263 /// Double wrapper type from Protocol Buffers.
264 ///
265 /// This corresponds to `google.protobuf.DoubleValue`.
266 DoubleWrapper,
267
268 /// String wrapper type from Protocol Buffers.
269 ///
270 /// This corresponds to `google.protobuf.StringValue`.
271 StringWrapper,
272
273 /// Bytes wrapper type from Protocol Buffers.
274 ///
275 /// This corresponds to `google.protobuf.BytesValue`.
276 BytesWrapper,
277
278 /// Type parameter type - used in generic type definitions.
279 ///
280 /// This represents type parameters in generic contexts.
281 TypeParam(TypeParamType),
282
283 /// Function type - represents function signatures.
284 ///
285 /// This is used to represent the types of functions and their signatures.
286 Function(FunctionType),
287
288 /// Enum type - represents enumeration types.
289 ///
290 /// This corresponds to Protocol Buffer enum types.
291 Enum(EnumType),
292}
293
294impl ValueType {
295 /// Returns the kind of this type.
296 ///
297 /// The kind represents the basic category of the type, which is useful
298 /// for type checking and dispatch logic.
299 ///
300 /// # Examples
301 ///
302 /// ```rust,no_run
303 /// use cel_cxx::*;
304 ///
305 /// assert_eq!(ValueType::Int.kind(), Kind::Int);
306 /// assert_eq!(ValueType::String.kind(), Kind::String);
307 ///
308 /// let list_type = ValueType::List(ListType::new(ValueType::Int));
309 /// assert_eq!(list_type.kind(), Kind::List);
310 /// ```
311 pub fn kind(&self) -> Kind {
312 match self {
313 ValueType::Null => Kind::Null,
314
315 ValueType::Bool => Kind::Bool,
316 ValueType::Int => Kind::Int,
317 ValueType::Uint => Kind::Uint,
318 ValueType::Double => Kind::Double,
319 ValueType::String => Kind::String,
320 ValueType::Bytes => Kind::Bytes,
321
322 ValueType::Struct(_) => Kind::Struct,
323 ValueType::Duration => Kind::Duration,
324 ValueType::Timestamp => Kind::Timestamp,
325
326 ValueType::List(_) => Kind::List,
327 ValueType::Map(_) => Kind::Map,
328
329 ValueType::Unknown => Kind::Unknown,
330 ValueType::Type(_) => Kind::Type,
331 ValueType::Error => Kind::Error,
332 ValueType::Any => Kind::Any,
333
334 ValueType::Dyn => Kind::Dyn,
335 ValueType::Opaque(_) | ValueType::Optional(_) => Kind::Opaque,
336
337 ValueType::BoolWrapper => Kind::BoolWrapper,
338 ValueType::IntWrapper => Kind::IntWrapper,
339 ValueType::UintWrapper => Kind::UintWrapper,
340 ValueType::DoubleWrapper => Kind::DoubleWrapper,
341 ValueType::StringWrapper => Kind::StringWrapper,
342 ValueType::BytesWrapper => Kind::BytesWrapper,
343
344 ValueType::TypeParam(_) => Kind::TypeParam,
345 ValueType::Function(_) => Kind::Function,
346 ValueType::Enum(_) => Kind::Enum,
347 }
348 }
349
350 /// Checks if this type matches the type of a specific [`TypedValue`] implementation.
351 ///
352 /// This method provides a type-safe way to check if a [`ValueType`] corresponds
353 /// to a particular Rust type that implements [`TypedValue`]. It's particularly
354 /// useful for runtime type checking and validation.
355 ///
356 /// # Type Parameters
357 ///
358 /// * `T` - A type that implements [`TypedValue`], representing the Rust type to check against
359 ///
360 /// # Returns
361 ///
362 /// Returns `true` if this [`ValueType`] matches the CEL type representation of `T`,
363 /// `false` otherwise.
364 ///
365 /// # Examples
366 ///
367 /// ## Basic Type Checking
368 ///
369 /// ```rust,no_run
370 /// use cel_cxx::*;
371 ///
372 /// // Check primitive types
373 /// assert!(ValueType::Int.is::<i64>());
374 /// assert!(ValueType::String.is::<String>());
375 /// assert!(ValueType::Bool.is::<bool>());
376 ///
377 /// // Check against wrong types
378 /// assert!(!ValueType::Int.is::<String>());
379 /// assert!(!ValueType::String.is::<bool>());
380 /// ```
381 ///
382 /// ## Collection Type Checking
383 ///
384 /// ```rust,no_run
385 /// use cel_cxx::*;
386 /// use std::collections::HashMap;
387 ///
388 /// let list_type = ValueType::List(ListType::new(ValueType::Int));
389 /// let map_type = ValueType::Map(MapType::new(MapKeyType::String, ValueType::Int));
390 ///
391 /// // Check collection types
392 /// assert!(list_type.is::<Vec<i64>>());
393 /// assert!(map_type.is::<HashMap<String, i64>>());
394 ///
395 /// // Check against incompatible collection types
396 /// assert!(!list_type.is::<Vec<String>>());
397 /// assert!(!map_type.is::<HashMap<i64, String>>());
398 /// ```
399 ///
400 /// ## Optional Type Checking
401 ///
402 /// ```rust,no_run
403 /// use cel_cxx::*;
404 ///
405 /// let optional_string = ValueType::Optional(OptionalType::new(ValueType::String));
406 ///
407 /// // Check optional types
408 /// assert!(optional_string.is::<Option<String>>());
409 /// assert!(!optional_string.is::<Option<i64>>());
410 /// assert!(!optional_string.is::<String>()); // Not optional
411 /// ```
412 ///
413 /// ## Custom Opaque Type Checking
414 ///
415 /// ```rust,no_run
416 /// use cel_cxx::*;
417 ///
418 /// #[derive(Opaque, Debug, Clone, PartialEq)]
419 /// #[cel_cxx(type = "my.CustomType")]
420 /// struct CustomType {
421 /// value: i32,
422 /// }
423 /// impl std::fmt::Display for CustomType {
424 /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
425 /// write!(f, "CustomType({})", self.value)
426 /// }
427 /// }
428 ///
429 /// let opaque_type = <CustomType as TypedValue>::value_type();
430 ///
431 /// // Check custom opaque type
432 /// assert!(opaque_type.is::<CustomType>());
433 /// assert!(!opaque_type.is::<i32>());
434 /// ```
435 ///
436 /// # Use Cases
437 ///
438 /// This method is commonly used in:
439 /// - **Function implementations**: Validating argument types before processing
440 /// - **Type guards**: Ensuring type safety in generic contexts
441 /// - **Error handling**: Providing detailed type mismatch error messages
442 /// - **Debugging**: Runtime inspection of type compatibility
443 ///
444 /// # See Also
445 ///
446 /// - [`TypedValue::value_type()`]: Get the [`ValueType`] representation of a Rust type
447 /// - [`ValueType::kind()`]: Get the basic kind category of a type
448 pub fn is<T: TypedValue>(&self) -> bool {
449 T::value_type() == *self
450 }
451}
452
453/// Struct type for Protocol Buffer messages.
454///
455/// This represents a structured type, typically corresponding to a Protocol Buffer
456/// message type. Struct types are identified by their fully qualified name.
457///
458/// # Examples
459///
460/// ```rust,no_run
461/// use cel_cxx::*;
462///
463/// let struct_type = StructType::new("google.protobuf.Duration");
464/// let type_instance = ValueType::Struct(struct_type);
465/// ```
466#[derive(Clone, Debug, Hash, PartialEq, Eq)]
467pub struct StructType {
468 /// The fully qualified name of the struct type.
469 pub name: String,
470}
471
472impl StructType {
473 /// Creates a new struct type with the given name.
474 ///
475 /// # Arguments
476 ///
477 /// * `name` - The fully qualified name of the struct type
478 ///
479 /// # Examples
480 ///
481 /// ```rust,no_run
482 /// use cel_cxx::*;
483 ///
484 /// let struct_type = StructType::new("my.package.MyMessage");
485 /// ```
486 pub fn new<S: Into<String>>(name: S) -> Self {
487 Self { name: name.into() }
488 }
489}
490
491/// List type representing ordered collections.
492///
493/// List types specify the type of elements they contain. All elements in a
494/// CEL list must be of the same type (or compatible types).
495///
496/// # Examples
497///
498/// ```rust,no_run
499/// use cel_cxx::*;
500///
501/// // List of integers: list<int>
502/// let int_list = ListType::new(ValueType::Int);
503///
504/// // List of strings: list<string>
505/// let string_list = ListType::new(ValueType::String);
506///
507/// // Nested list: list<list<int>>
508/// let nested_list = ListType::new(ValueType::List(int_list));
509/// ```
510#[derive(Clone, Debug, Hash, PartialEq, Eq)]
511pub struct ListType {
512 /// The type of elements in this list.
513 pub element: Box<ValueType>,
514}
515
516impl ListType {
517 /// Creates a new list type with the given element type.
518 ///
519 /// # Arguments
520 ///
521 /// * `element` - The type of elements in the list
522 ///
523 /// # Examples
524 ///
525 /// ```rust,no_run
526 /// use cel_cxx::*;
527 ///
528 /// let list_type = ListType::new(ValueType::String);
529 /// assert_eq!(list_type.element(), &ValueType::String);
530 /// ```
531 pub fn new(element: ValueType) -> Self {
532 Self {
533 element: Box::new(element),
534 }
535 }
536
537 /// Returns the element type of this list.
538 ///
539 /// # Examples
540 ///
541 /// ```rust,no_run
542 /// use cel_cxx::*;
543 ///
544 /// let list_type = ListType::new(ValueType::Int);
545 /// assert_eq!(list_type.element(), &ValueType::Int);
546 /// ```
547 pub fn element(&self) -> &ValueType {
548 &self.element
549 }
550}
551
552/// Map type representing key-value mappings.
553///
554/// Map types specify both the type of keys and the type of values. Not all
555/// types can be used as map keys - only certain primitive types are allowed.
556///
557/// # Examples
558///
559/// ```rust,no_run
560/// use cel_cxx::*;
561///
562/// // Map from string to int: map<string, int>
563/// let string_to_int = MapType::new(MapKeyType::String, ValueType::Int);
564///
565/// // Map from int to list of strings: map<int, list<string>>
566/// let complex_map = MapType::new(
567/// MapKeyType::Int,
568/// ValueType::List(ListType::new(ValueType::String))
569/// );
570/// ```
571#[derive(Clone, Debug, Hash, PartialEq, Eq)]
572pub struct MapType {
573 /// The type of keys in this map.
574 pub key: MapKeyType,
575 /// The type of values in this map.
576 pub value: Box<ValueType>,
577}
578
579impl MapType {
580 /// Creates a new map type with the given key and value types.
581 ///
582 /// # Arguments
583 ///
584 /// * `key` - The type of keys in the map
585 /// * `value` - The type of values in the map
586 ///
587 /// # Examples
588 ///
589 /// ```rust,no_run
590 /// use cel_cxx::*;
591 ///
592 /// let map_type = MapType::new(MapKeyType::String, ValueType::Int);
593 /// assert_eq!(map_type.key(), &MapKeyType::String);
594 /// assert_eq!(map_type.value(), &ValueType::Int);
595 /// ```
596 pub fn new(key: MapKeyType, value: ValueType) -> Self {
597 Self {
598 key,
599 value: Box::new(value),
600 }
601 }
602
603 /// Returns the key type of this map.
604 ///
605 /// # Examples
606 ///
607 /// ```rust,no_run
608 /// use cel_cxx::*;
609 ///
610 /// let map_type = MapType::new(MapKeyType::Int, ValueType::String);
611 /// assert_eq!(map_type.key(), &MapKeyType::Int);
612 /// ```
613 pub fn key(&self) -> &MapKeyType {
614 &self.key
615 }
616
617 /// Returns the value type of this map.
618 ///
619 /// # Examples
620 ///
621 /// ```rust,no_run
622 /// use cel_cxx::*;
623 ///
624 /// let map_type = MapType::new(MapKeyType::String, ValueType::Double);
625 /// assert_eq!(map_type.value(), &ValueType::Double);
626 /// ```
627 pub fn value(&self) -> &ValueType {
628 &self.value
629 }
630}
631
632/// Type type representing type values.
633///
634/// This represents CEL's type system where types themselves can be values.
635/// For example, the expression `type(42)` returns a type value representing `int`.
636///
637/// # Examples
638///
639/// ```rust,no_run
640/// use cel_cxx::*;
641///
642/// // Generic type: type
643/// let generic_type = TypeType::new(None);
644///
645/// // Parameterized type: type<string>
646/// let parameterized_type = TypeType::new(Some(ValueType::String));
647/// ```
648#[derive(Clone, Debug, Hash, PartialEq, Eq)]
649pub struct TypeType {
650 /// Optional type parameter for parameterized types.
651 pub parameter: Option<Box<ValueType>>,
652}
653
654impl TypeType {
655 /// Creates a new type type with an optional parameter.
656 ///
657 /// # Arguments
658 ///
659 /// * `parameter` - Optional type parameter
660 ///
661 /// # Examples
662 ///
663 /// ```rust,no_run
664 /// use cel_cxx::*;
665 ///
666 /// // Generic type
667 /// let generic = TypeType::new(None);
668 ///
669 /// // Specific type
670 /// let specific = TypeType::new(Some(ValueType::String));
671 /// ```
672 pub fn new(parameter: Option<ValueType>) -> Self {
673 Self {
674 parameter: parameter.map(Box::new),
675 }
676 }
677
678 /// Returns the type parameter if present.
679 ///
680 /// # Examples
681 ///
682 /// ```rust,no_run
683 /// use cel_cxx::*;
684 ///
685 /// let type_type = TypeType::new(Some(ValueType::Int));
686 /// assert_eq!(type_type.parameter(), Some(&ValueType::Int));
687 /// ```
688 pub fn parameter(&self) -> Option<&ValueType> {
689 self.parameter.as_deref()
690 }
691}
692
693/// Opaque type for user-defined types.
694///
695/// Opaque types allow you to integrate custom Rust types into CEL expressions.
696/// They are identified by name and can have type parameters for generic types.
697///
698/// # Examples
699///
700/// ```rust,no_run
701/// use cel_cxx::*;
702///
703/// // Simple opaque type: MyType
704/// let simple = OpaqueType::new("MyType", vec![]);
705///
706/// // Generic opaque type: MyGeneric<string, int>
707/// let generic = OpaqueType::new("MyGeneric", vec![ValueType::String, ValueType::Int]);
708/// ```
709#[derive(Clone, Debug, Hash, PartialEq, Eq)]
710pub struct OpaqueType {
711 /// The name of the opaque type.
712 pub name: String,
713 /// Type parameters for generic opaque types.
714 pub parameters: Vec<ValueType>,
715}
716
717impl OpaqueType {
718 /// Creates a new opaque type with the given name and type parameters.
719 ///
720 /// # Arguments
721 ///
722 /// * `name` - The name of the opaque type
723 /// * `parameters` - Type parameters for generic opaque types
724 ///
725 /// # Examples
726 ///
727 /// ```rust,no_run
728 /// use cel_cxx::*;
729 ///
730 /// // Simple opaque type
731 /// let simple = OpaqueType::new("MyType", vec![]);
732 ///
733 /// // Generic opaque type
734 /// let generic = OpaqueType::new("Container", vec![ValueType::String]);
735 /// ```
736 pub fn new<S: Into<String>>(name: S, parameters: Vec<ValueType>) -> Self {
737 Self {
738 name: name.into(),
739 parameters,
740 }
741 }
742
743 /// Returns the name of this opaque type.
744 ///
745 /// # Examples
746 ///
747 /// ```rust,no_run
748 /// use cel_cxx::*;
749 ///
750 /// let opaque_type = OpaqueType::new("MyType", vec![]);
751 /// assert_eq!(opaque_type.name(), "MyType");
752 /// ```
753 pub fn name(&self) -> &str {
754 &self.name
755 }
756
757 /// Returns the type parameters of this opaque type.
758 ///
759 /// # Examples
760 ///
761 /// ```rust,no_run
762 /// use cel_cxx::*;
763 ///
764 /// let opaque_type = OpaqueType::new("Container", vec![ValueType::Int, ValueType::String]);
765 /// assert_eq!(opaque_type.parameters().len(), 2);
766 /// ```
767 pub fn parameters(&self) -> &[ValueType] {
768 &self.parameters
769 }
770}
771
772/// Optional type representing values that may or may not be present.
773///
774/// Optional types wrap another type to indicate that values of that type
775/// may be absent. This is similar to Rust's `Option<T>` type.
776///
777/// # Examples
778///
779/// ```rust,no_run
780/// use cel_cxx::*;
781///
782/// // Optional string: optional<string>
783/// let optional_string = OptionalType::new(ValueType::String);
784///
785/// // Optional list: optional<list<int>>
786/// let optional_list = OptionalType::new(
787/// ValueType::List(ListType::new(ValueType::Int))
788/// );
789/// ```
790#[derive(Clone, Debug, Hash, PartialEq, Eq)]
791pub struct OptionalType {
792 /// The type that may or may not be present.
793 pub parameter: Box<ValueType>,
794}
795
796impl OptionalType {
797 /// Creates a new optional type wrapping the given type.
798 ///
799 /// # Arguments
800 ///
801 /// * `parameter` - The type that may be optional
802 ///
803 /// # Examples
804 ///
805 /// ```rust,no_run
806 /// use cel_cxx::*;
807 ///
808 /// let optional_int = OptionalType::new(ValueType::Int);
809 /// assert_eq!(optional_int.parameter(), &ValueType::Int);
810 /// ```
811 pub fn new(parameter: ValueType) -> Self {
812 Self {
813 parameter: Box::new(parameter),
814 }
815 }
816
817 /// Returns the wrapped type.
818 ///
819 /// # Examples
820 ///
821 /// ```rust,no_run
822 /// use cel_cxx::*;
823 ///
824 /// let optional_string = OptionalType::new(ValueType::String);
825 /// assert_eq!(optional_string.parameter(), &ValueType::String);
826 /// ```
827 pub fn parameter(&self) -> &ValueType {
828 &self.parameter
829 }
830}
831
832/// Type parameter type used in generic type definitions.
833///
834/// Type parameters represent placeholders for types in generic contexts.
835/// They are typically used in function signatures and generic type definitions.
836///
837/// # Examples
838///
839/// ```rust,no_run
840/// use cel_cxx::*;
841///
842/// let type_param = TypeParamType::new("T");
843/// assert_eq!(type_param.name(), "T");
844/// ```
845#[derive(Clone, Debug, Hash, PartialEq, Eq)]
846pub struct TypeParamType {
847 /// The name of the type parameter.
848 pub name: String,
849}
850
851impl TypeParamType {
852 /// Creates a new type parameter with the given name.
853 ///
854 /// # Arguments
855 ///
856 /// * `name` - The name of the type parameter (e.g., "T", "U", "Key", "Value")
857 ///
858 /// # Examples
859 ///
860 /// ```rust,no_run
861 /// use cel_cxx::*;
862 ///
863 /// let type_param = TypeParamType::new("T");
864 /// let another_param = TypeParamType::new("Key");
865 /// ```
866 pub fn new<S: Into<String>>(name: S) -> Self {
867 Self { name: name.into() }
868 }
869
870 /// Returns the name of this type parameter.
871 ///
872 /// # Examples
873 ///
874 /// ```rust,no_run
875 /// use cel_cxx::*;
876 ///
877 /// let type_param = TypeParamType::new("T");
878 /// assert_eq!(type_param.name(), "T");
879 /// ```
880 pub fn name(&self) -> &str {
881 &self.name
882 }
883}
884
885/// Function type representing function signatures.
886///
887/// Function types describe the signature of functions, including their
888/// parameter types and return type. This is used for type checking
889/// function calls and declarations.
890///
891/// # Examples
892///
893/// ```rust,no_run
894/// use cel_cxx::*;
895///
896/// // Function type: (string, int) -> bool
897/// let func_type = FunctionType::new(
898/// ValueType::Bool,
899/// vec![ValueType::String, ValueType::Int]
900/// );
901///
902/// // No-argument function: () -> string
903/// let no_arg_func = FunctionType::new(ValueType::String, vec![]);
904/// ```
905#[derive(Clone, Debug, Hash, PartialEq, Eq)]
906pub struct FunctionType {
907 /// The return type of the function.
908 pub result: Box<ValueType>,
909 /// The parameter types of the function.
910 pub arguments: Vec<ValueType>,
911}
912
913impl FunctionType {
914 /// Creates a new function type with the given return type and parameters.
915 ///
916 /// # Arguments
917 ///
918 /// * `result` - The return type of the function
919 /// * `arguments` - The parameter types of the function
920 ///
921 /// # Examples
922 ///
923 /// ```rust,no_run
924 /// use cel_cxx::*;
925 ///
926 /// // Function that takes two ints and returns a string
927 /// let func_type = FunctionType::new(
928 /// ValueType::String,
929 /// vec![ValueType::Int, ValueType::Int]
930 /// );
931 /// ```
932 pub fn new(result: ValueType, arguments: Vec<ValueType>) -> Self {
933 Self {
934 result: Box::new(result),
935 arguments,
936 }
937 }
938
939 /// Returns the return type of this function.
940 ///
941 /// # Examples
942 ///
943 /// ```rust,no_run
944 /// use cel_cxx::*;
945 ///
946 /// let func_type = FunctionType::new(ValueType::Bool, vec![ValueType::String]);
947 /// assert_eq!(func_type.result(), &ValueType::Bool);
948 /// ```
949 pub fn result(&self) -> &ValueType {
950 &self.result
951 }
952
953 /// Returns the parameter types of this function.
954 ///
955 /// # Examples
956 ///
957 /// ```rust,no_run
958 /// use cel_cxx::*;
959 ///
960 /// let func_type = FunctionType::new(ValueType::Int, vec![ValueType::String, ValueType::Bool]);
961 /// assert_eq!(func_type.arguments().len(), 2);
962 /// ```
963 pub fn arguments(&self) -> &[ValueType] {
964 &self.arguments
965 }
966
967 /// Generates a unique identifier for this function type.
968 ///
969 /// This creates a string representation of the function signature that
970 /// can be used for function resolution and overload disambiguation.
971 ///
972 /// # Arguments
973 ///
974 /// * `name` - The name of the function
975 /// * `member` - Whether this is a member function
976 ///
977 /// # Examples
978 ///
979 /// ```rust,no_run
980 /// use cel_cxx::*;
981 ///
982 /// let func_type = FunctionType::new(ValueType::Int, vec![ValueType::String]);
983 /// let id = func_type.id("myFunc", false);
984 /// // Results in something like "myFunc(string)"
985 /// ```
986 pub fn id(&self, name: &str, member: bool) -> String {
987 use itertools::Itertools;
988 if member && !self.arguments.is_empty() {
989 format!(
990 "({}).{}({})",
991 self.arguments[0],
992 name,
993 self.arguments[1..].iter().format(", ")
994 )
995 } else {
996 format!("{}({})", name, self.arguments.iter().format(", "))
997 }
998 }
999}
1000
1001/// Enum type representing enumeration types.
1002///
1003/// Enum types correspond to Protocol Buffer enum types and represent
1004/// a fixed set of named integer constants.
1005///
1006/// # Examples
1007///
1008/// ```rust,no_run
1009/// use cel_cxx::*;
1010///
1011/// let enum_type = EnumType::new("my.package.Color");
1012/// assert_eq!(enum_type.name(), "my.package.Color");
1013/// ```
1014#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1015pub struct EnumType {
1016 /// The fully qualified name of the enum type.
1017 pub name: String,
1018}
1019
1020impl EnumType {
1021 /// Creates a new enum type with the given name.
1022 ///
1023 /// # Arguments
1024 ///
1025 /// * `name` - The fully qualified name of the enum type
1026 ///
1027 /// # Examples
1028 ///
1029 /// ```rust,no_run
1030 /// use cel_cxx::*;
1031 ///
1032 /// let enum_type = EnumType::new("google.rpc.Code");
1033 /// ```
1034 pub fn new<S: Into<String>>(name: S) -> Self {
1035 Self { name: name.into() }
1036 }
1037
1038 /// Returns the name of this enum type.
1039 ///
1040 /// # Examples
1041 ///
1042 /// ```rust,no_run
1043 /// use cel_cxx::*;
1044 ///
1045 /// let enum_type = EnumType::new("my.Status");
1046 /// assert_eq!(enum_type.name(), "my.Status");
1047 /// ```
1048 pub fn name(&self) -> &str {
1049 &self.name
1050 }
1051}
1052
1053/// Types that can be used as map keys.
1054///
1055/// CEL maps can only use certain types as keys. This enum represents
1056/// the allowed key types in CEL map literals and map type definitions.
1057///
1058/// # Examples
1059///
1060/// ```rust,no_run
1061/// use cel_cxx::*;
1062///
1063/// // String keys are common
1064/// let string_key_map = MapType::new(MapKeyType::String, ValueType::Int);
1065///
1066/// // Integer keys are also supported
1067/// let int_key_map = MapType::new(MapKeyType::Int, ValueType::String);
1068///
1069/// // Check the kind of a key type
1070/// assert_eq!(MapKeyType::String.kind(), Kind::String);
1071/// ```
1072///
1073/// # Note
1074///
1075/// Not all CEL types can be used as map keys. Only primitive types that
1076/// are hashable and comparable are allowed.
1077#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1078#[repr(u8)]
1079pub enum MapKeyType {
1080 /// Boolean keys - `true` and `false`.
1081 Bool,
1082
1083 /// Signed integer keys.
1084 Int,
1085
1086 /// Unsigned integer keys.
1087 Uint,
1088
1089 /// String keys (most common).
1090 String,
1091
1092 /// Dynamic key type - determined at runtime.
1093 Dyn,
1094
1095 /// Type parameter key type - used in generic contexts.
1096 TypeParam(TypeParamType),
1097}
1098
1099impl MapKeyType {
1100 /// Returns the kind of this map key type.
1101 ///
1102 /// This provides the basic category of the key type for type checking
1103 /// and dispatch purposes.
1104 ///
1105 /// # Examples
1106 ///
1107 /// ```rust,no_run
1108 /// use cel_cxx::*;
1109 ///
1110 /// assert_eq!(MapKeyType::String.kind(), Kind::String);
1111 /// assert_eq!(MapKeyType::Int.kind(), Kind::Int);
1112 /// assert_eq!(MapKeyType::Bool.kind(), Kind::Bool);
1113 /// ```
1114 pub fn kind(&self) -> Kind {
1115 match self {
1116 MapKeyType::Bool => Kind::Bool,
1117 MapKeyType::Int => Kind::Int,
1118 MapKeyType::Uint => Kind::Uint,
1119 MapKeyType::String => Kind::String,
1120 MapKeyType::Dyn => Kind::Dyn,
1121 MapKeyType::TypeParam(_) => Kind::TypeParam,
1122 }
1123 }
1124}