cel_cxx_ffi/common/
kind.rs

1use crate::absl::SpanElement;
2use crate::absl::StringView;
3
4#[cxx::bridge]
5mod ffi {
6    #[namespace = "absl"]
7    unsafe extern "C++" {
8        include!(<absl/strings/string_view.h>);
9        type string_view<'a> = super::StringView<'a>;
10    }
11
12    #[namespace = "cel"]
13    unsafe extern "C++" {
14        include!(<base/kind.h>);
15        type Kind = super::Kind;
16        fn KindToString(kind: Kind) -> string_view<'static>;
17
18        type TypeKind = super::TypeKind;
19        fn TypeKindToKind(kind: TypeKind) -> Kind;
20        fn KindIsTypeKind(kind: Kind) -> bool;
21        fn TypeKindToString(kind: TypeKind) -> string_view<'static>;
22        fn KindToTypeKind(kind: Kind) -> TypeKind;
23
24        type ValueKind = super::ValueKind;
25        fn ValueKindToKind(kind: ValueKind) -> Kind;
26        fn KindIsValueKind(kind: Kind) -> bool;
27        fn ValueKindToString(kind: ValueKind) -> string_view<'static>;
28        fn KindToValueKind(kind: Kind) -> ValueKind;
29    }
30}
31
32/// Represents the fundamental type categories in CEL.
33///
34/// This enum corresponds to the `Kind` type in CEL-CPP and serves as the base type
35/// classification system for CEL values and types. It provides a unified way to
36/// represent both value types and type kinds in the CEL type system.
37///
38/// # Variants
39///
40/// ## Primitive Types
41/// - `Null` - The null value type
42/// - `Bool` - Boolean values
43/// - `Int` - 64-bit signed integers
44/// - `Uint` - 64-bit unsigned integers
45/// - `Double` - 64-bit floating-point numbers
46/// - `String` - UTF-8 encoded strings
47/// - `Bytes` - Raw byte sequences
48///
49/// ## Complex Types
50/// - `Struct` - Structured data types
51/// - `List` - Homogeneous lists
52/// - `Map` - Key-value mappings
53///
54/// ## Protocol Buffer Types
55/// - `Duration` - Time duration values
56/// - `Timestamp` - Point-in-time values
57/// - `BoolWrapper` - Protocol buffer bool wrapper
58/// - `IntWrapper` - Protocol buffer int64 wrapper
59/// - `UintWrapper` - Protocol buffer uint64 wrapper
60/// - `DoubleWrapper` - Protocol buffer double wrapper
61/// - `StringWrapper` - Protocol buffer string wrapper
62/// - `BytesWrapper` - Protocol buffer bytes wrapper
63///
64/// ## Special Types
65/// - `Unknown` - Type not yet determined
66/// - `Type` - Type of a type (meta-type)
67/// - `Error` - Error type
68/// - `Any` - Dynamic type that can hold any value
69/// - `Dyn` - Dynamic type for runtime type checking
70/// - `Opaque` - Custom opaque types
71/// - `TypeParam` - Type parameter in generic types
72/// - `Function` - Function type
73/// - `Enum` - Enumeration type
74#[repr(u8)]
75#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
76pub enum Kind {
77    Null = 0,
78    Bool,
79    Int,
80    Uint,
81    Double,
82    String,
83    Bytes,
84    Struct,
85    Duration,
86    Timestamp,
87    List,
88    Map,
89    Unknown,
90    Type,
91    Error,
92    Any,
93
94    Dyn,
95    Opaque,
96
97    BoolWrapper,
98    IntWrapper,
99    UintWrapper,
100    DoubleWrapper,
101    StringWrapper,
102    BytesWrapper,
103
104    TypeParam,
105    Function,
106    Enum,
107}
108
109unsafe impl cxx::ExternType for Kind {
110    type Id = cxx::type_id!("cel::Kind");
111    type Kind = cxx::kind::Trivial;
112}
113
114impl crate::SizedExternType for Kind {}
115impl SpanElement for Kind {
116    type TypeId = cxx::type_id!("rust::cel_cxx::Span_Kind");
117}
118
119impl std::fmt::Display for Kind {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        f.write_str(
122            ffi::KindToString(*self)
123                .to_str()
124                .map_err(|_| std::fmt::Error)?,
125        )
126    }
127}
128
129impl Kind {
130    pub fn is_type_kind(&self) -> bool {
131        ffi::KindIsTypeKind(*self)
132    }
133
134    pub fn is_value_kind(&self) -> bool {
135        ffi::KindIsValueKind(*self)
136    }
137}
138
139/// Represents the type kinds in CEL's type system.
140///
141/// This enum is a subset of [`Kind`] that specifically represents type kinds
142/// in the CEL type system. It is used for type checking and type inference
143/// operations. Each variant corresponds to a specific type category that can
144/// be used in type declarations and type checking.
145///
146/// # Relationship with [`Kind`]
147///
148/// `TypeKind` is a specialized view of [`Kind`] that only includes variants
149/// relevant to type system operations. It maintains the same variant values
150/// as [`Kind`] for compatibility, but provides a more focused interface for
151/// type-related operations.
152///
153/// # Examples
154///
155/// ```rust
156/// use cel_cxx_ffi::common::{Kind, TypeKind};
157///
158/// // TypeKind can be converted to Kind
159/// let type_kind = TypeKind::Int;
160/// let kind: Kind = type_kind.into();
161/// assert!(kind.is_type_kind());
162/// ```
163#[repr(u8)]
164#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
165pub enum TypeKind {
166    Null = Kind::Null as u8,
167    Bool = Kind::Bool as u8,
168    Int = Kind::Int as u8,
169    Uint = Kind::Uint as u8,
170    Double = Kind::Double as u8,
171    String = Kind::String as u8,
172    Bytes = Kind::Bytes as u8,
173    Struct = Kind::Struct as u8,
174    Duration = Kind::Duration as u8,
175    Timestamp = Kind::Timestamp as u8,
176    List = Kind::List as u8,
177    Map = Kind::Map as u8,
178    Unknown = Kind::Unknown as u8,
179    Type = Kind::Type as u8,
180    Error = Kind::Error as u8,
181    Any = Kind::Any as u8,
182    Dyn = Kind::Dyn as u8,
183    Opaque = Kind::Opaque as u8,
184
185    BoolWrapper = Kind::BoolWrapper as u8,
186    IntWrapper = Kind::IntWrapper as u8,
187    UintWrapper = Kind::UintWrapper as u8,
188    DoubleWrapper = Kind::DoubleWrapper as u8,
189    StringWrapper = Kind::StringWrapper as u8,
190    BytesWrapper = Kind::BytesWrapper as u8,
191
192    TypeParam = Kind::TypeParam as u8,
193    Function = Kind::Function as u8,
194    Enum = Kind::Enum as u8,
195}
196
197unsafe impl cxx::ExternType for TypeKind {
198    type Id = cxx::type_id!("cel::TypeKind");
199    type Kind = cxx::kind::Trivial;
200}
201
202impl crate::SizedExternType for TypeKind {}
203impl SpanElement for TypeKind {
204    type TypeId = cxx::type_id!("rust::cel_cxx::Span_TypeKind");
205}
206
207impl std::fmt::Display for TypeKind {
208    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
209        f.write_str(
210            ffi::TypeKindToString(*self)
211                .to_str()
212                .map_err(|_| std::fmt::Error)?,
213        )
214    }
215}
216
217/// Represents the value kinds in CEL's value system.
218///
219/// This enum is a subset of [`Kind`] that specifically represents value kinds
220/// in the CEL value system. It is used for runtime value type checking and
221/// value operations. Each variant corresponds to a specific value category
222/// that can be used in value operations and runtime type checking.
223///
224/// # Relationship with [`Kind`]
225///
226/// `ValueKind` is a specialized view of [`Kind`] that only includes variants
227/// relevant to value operations. It maintains the same variant values as [`Kind`]
228/// for compatibility, but provides a more focused interface for value-related
229/// operations.
230///
231/// # Examples
232///
233/// ```rust
234/// use cel_cxx_ffi::common::{Kind, ValueKind};
235///
236/// // ValueKind can be converted to Kind
237/// let value_kind = ValueKind::Int;
238/// let kind: Kind = value_kind.into();
239/// assert!(kind.is_value_kind());
240///
241/// // Not all Kind variants are valid ValueKinds
242/// assert!(Kind::Int.is_value_kind());
243/// assert!(!Kind::Function.is_value_kind());
244/// ```
245#[repr(u8)]
246#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
247pub enum ValueKind {
248    Null = Kind::Null as u8,
249    Bool = Kind::Bool as u8,
250    Int = Kind::Int as u8,
251    Uint = Kind::Uint as u8,
252    Double = Kind::Double as u8,
253    String = Kind::String as u8,
254    Bytes = Kind::Bytes as u8,
255    Struct = Kind::Struct as u8,
256    Duration = Kind::Duration as u8,
257    Timestamp = Kind::Timestamp as u8,
258    List = Kind::List as u8,
259    Map = Kind::Map as u8,
260    Unknown = Kind::Unknown as u8,
261    Type = Kind::Type as u8,
262    Error = Kind::Error as u8,
263    Opaque = Kind::Opaque as u8,
264}
265
266unsafe impl cxx::ExternType for ValueKind {
267    type Id = cxx::type_id!("cel::ValueKind");
268    type Kind = cxx::kind::Trivial;
269}
270
271impl crate::SizedExternType for ValueKind {}
272impl SpanElement for ValueKind {
273    type TypeId = cxx::type_id!("rust::cel_cxx::Span_ValueKind");
274}
275
276impl std::fmt::Display for ValueKind {
277    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
278        f.write_str(
279            ffi::ValueKindToString(*self)
280                .to_str()
281                .map_err(|_| std::fmt::Error)?,
282        )
283    }
284}
285
286impl From<Kind> for TypeKind {
287    fn from(kind: Kind) -> Self {
288        ffi::KindToTypeKind(kind)
289    }
290}
291
292impl From<Kind> for ValueKind {
293    fn from(kind: Kind) -> Self {
294        ffi::KindToValueKind(kind)
295    }
296}
297
298impl From<TypeKind> for Kind {
299    fn from(kind: TypeKind) -> Self {
300        ffi::TypeKindToKind(kind)
301    }
302}
303
304impl From<ValueKind> for Kind {
305    fn from(kind: ValueKind) -> Self {
306        ffi::ValueKindToKind(kind)
307    }
308}
309
310impl std::cmp::PartialEq<TypeKind> for Kind {
311    fn eq(&self, other: &TypeKind) -> bool {
312        *self == ffi::TypeKindToKind(*other)
313    }
314}
315
316impl std::cmp::PartialEq<ValueKind> for Kind {
317    fn eq(&self, other: &ValueKind) -> bool {
318        *self == ffi::ValueKindToKind(*other)
319    }
320}
321
322impl std::cmp::PartialEq<Kind> for TypeKind {
323    fn eq(&self, other: &Kind) -> bool {
324        ffi::TypeKindToKind(*self) == *other
325    }
326}
327
328impl std::cmp::PartialEq<Kind> for ValueKind {
329    fn eq(&self, other: &Kind) -> bool {
330        ffi::ValueKindToKind(*self) == *other
331    }
332}