1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
//use std::{ops::Deref, sync::Arc};
use *;
/// Trait for opaque types that can be stored in CEL values.
///
/// This trait allows custom Rust types to be embedded in CEL values as opaque
/// objects. Opaque types are useful for:
/// - **Foreign data structures**: Types from other libraries
/// - **Complex business objects**: Domain-specific data models
/// - **Native performance**: Keep computations in native Rust
/// - **Type safety**: Maintain strong typing across CEL boundaries
///
/// # Opaque Type Characteristics
///
/// Opaque values in CEL:
/// - Cannot be directly manipulated by CEL expressions
/// - Can be passed between functions that understand the type
/// - Support method calls through registered member functions
/// - Maintain their Rust type identity and behavior
///
/// # Required Traits
///
/// Implementing `Opaque` requires several standard traits:
/// - [`Clone`]: For value duplication
/// - [`Debug`]: For debugging and error messages
/// - [`std::fmt::Display`]: For string representation
/// - [`Send + Sync`]: For thread safety
/// - [`dyn_clone::DynClone`]: For trait object cloning
///
/// # Examples
///
/// ## Basic Opaque Type
///
/// ```rust,no_run
/// use cel_cxx::{Opaque, Value, IntoValue};
///
/// #[derive(Opaque, Debug, Clone, PartialEq)]
/// #[cel_cxx(display)]
/// struct UserId(u64);
///
/// // All necessary traits are automatically implemented by the derive macro
///
/// // Usage in CEL values
/// let user_id = UserId(12345);
/// let value = user_id.into_value();
/// ```
///
/// ## Integration with Functions
///
/// ```rust,no_run
/// use cel_cxx::*;
///
/// #[derive(Opaque, Debug, Clone, PartialEq)]
/// #[cel_cxx(display)]
/// struct BankAccount {
/// balance: f64,
/// account_number: String,
/// }
///
/// impl BankAccount {
/// fn balance(&self) -> f64 {
/// self.balance
/// }
///
/// fn can_withdraw(&self, amount: f64) -> bool {
/// amount <= self.balance
/// }
///
/// fn account_number(&self) -> &str {
/// &self.account_number
/// }
/// }
///
/// // Register methods for the opaque type
/// let env = Env::builder()
/// .register_member_function("balance", BankAccount::balance)?
/// .register_member_function("can_withdraw", BankAccount::can_withdraw)?
/// .register_member_function("account_number", BankAccount::account_number)?
/// .build()?;
/// # Ok::<(), cel_cxx::Error>(())
/// ```
///
/// # Type Erasure and Downcasting
///
/// Opaque values support safe downcasting:
///
/// ```rust,no_run
/// use cel_cxx::{Value, Opaque, IntoValue};
///
/// #[derive(Opaque, Debug, Clone, PartialEq)]
/// #[cel_cxx(display)]
/// struct UserId(u64);
///
/// let user_id = UserId(12345);
/// let value = user_id.into_value();
///
/// // Safe downcasting
/// if let Value::Opaque(opaque) = &value {
/// if opaque.is::<UserId>() {
/// let user_id_ref = opaque.downcast_ref::<UserId>().unwrap();
/// println!("User ID: {}", user_id_ref.0);
/// }
/// }
/// ```
clone_trait_object!;
/// Trait for opaque types with additional type constraints.
///
/// This trait extends [`Opaque`] with additional requirements that enable
/// more sophisticated operations on opaque values. It adds:
/// - **Value equality**: Types can be compared for equality
/// - **Cloning**: Efficient cloning without heap allocation
/// - **Enhanced type safety**: Stronger compile-time guarantees
///
/// # When to Use TypedOpaque
///
/// Use `TypedOpaque` when your opaque type needs:
/// - Equality comparisons in CEL expressions
/// - Participation in hash-based collections
/// - Advanced type checking and validation
/// - Integration with CEL's type inference system
///
/// # Additional Requirements
///
/// Beyond [`Opaque`], this trait requires:
/// - [`Clone`]: Direct cloning (not just through trait objects)
/// - [`PartialEq`]: Value equality comparison
/// - All the traits required by [`Opaque`]
///
/// # Examples
///
/// ## Comparable Opaque Type
///
/// ```rust,no_run
/// use cel_cxx::Opaque;
///
/// #[derive(Opaque, Debug, Clone, PartialEq, Eq, Hash)]
/// #[cel_cxx(display)]
/// struct ProductId(String);
///
/// // All necessary traits are automatically implemented by the derive macro
/// ```