cel_cxx/marker.rs
1/// Marker trait for runtime types.
2///
3/// This trait is used to mark types that represent different async runtimes
4/// (such as Tokio or async-std) or the absence of an async runtime.
5///
6/// # Examples
7///
8/// ```rust,no_run
9/// use cel_cxx::marker::RuntimeMarker;
10///
11/// // The unit type represents no async runtime
12/// fn sync_example<R: RuntimeMarker>() {
13/// // This works with any runtime marker
14/// }
15/// ```
16pub trait RuntimeMarker: private::Sealed {}
17
18/// Implementation for the unit type (no async runtime).
19impl RuntimeMarker for () {}
20
21/// Marker trait for function types.
22///
23/// This trait is used to distinguish between synchronous and asynchronous
24/// functions in the type system. It allows the library to provide different
25/// behavior based on whether functions are sync or async.
26///
27/// # Examples
28///
29/// ```rust,no_run
30/// use cel_cxx::marker::FnMarker;
31///
32/// // The unit type represents synchronous functions
33/// fn sync_function_example<F: FnMarker>() {
34/// // This works with any function marker
35/// }
36/// ```
37pub trait FnMarker: private::Sealed {}
38
39/// Trait for aggregating function markers.
40///
41/// This trait is used to combine function markers from different sources
42/// (environment, activation, etc.) to determine the overall function
43/// capabilities of a context.
44///
45/// # Type Parameters
46///
47/// * `Other` - The other function marker to aggregate with
48///
49/// # Associated Types
50///
51/// * `Output` - The resulting function marker after aggregation
52///
53/// # Examples
54///
55/// ```rust,no_run
56/// use cel_cxx::marker::{FnMarker, FnMarkerAggr};
57///
58/// fn aggregate_example<F1, F2>()
59/// where
60/// F1: FnMarker + FnMarkerAggr<F2>,
61/// F2: FnMarker,
62/// {
63/// // F1::Output represents the combined capabilities
64/// }
65/// ```
66pub trait FnMarkerAggr<Other: FnMarker>: FnMarker {
67 /// The resulting function marker after aggregation.
68 type Output: FnMarker;
69}
70
71/// Trait for determining function result types.
72///
73/// This trait maps function markers to their corresponding result types.
74/// For synchronous functions, this is just the value type. For asynchronous
75/// functions, this wraps the value in a Future.
76///
77/// # Type Parameters
78///
79/// * `'a` - Lifetime parameter for the result
80/// * `T` - The base type that will be wrapped according to the marker
81///
82/// # Associated Types
83///
84/// * `Output` - The actual result type (T for sync, `Future<T>` for async)
85///
86/// # Examples
87///
88/// ```rust,no_run
89/// use cel_cxx::marker::{FnMarker, FnResult};
90///
91/// fn result_example<'a, F, T>() -> F::Output
92/// where
93/// F: FnMarker + FnResult<'a, T>,
94/// {
95/// // Return type depends on the function marker
96/// todo!()
97/// }
98/// ```
99pub trait FnResult<'a, T>: FnMarker {
100 /// The output type for this function marker and base type.
101 type Output;
102}
103
104/// Synchronous function marker implementation.
105///
106/// The unit type `()` represents synchronous functions.
107impl FnMarker for () {}
108
109/// Synchronous function aggregation.
110///
111/// Aggregating with synchronous functions yields synchronous functions.
112impl FnMarkerAggr<()> for () {
113 type Output = ();
114}
115
116/// Synchronous function results.
117///
118/// For synchronous functions, the result type is just the base type.
119impl<'a, T> FnResult<'a, T> for () {
120 type Output = T;
121}
122
123/// Async-specific marker types and implementations.
124///
125/// This module contains the marker types and trait implementations for
126/// asynchronous function support. It's only available when the `async`
127/// feature is enabled.
128#[cfg(feature = "async")]
129#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
130pub use async_marker::*;
131
132#[cfg(feature = "async")]
133#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
134mod async_marker {
135 use super::{FnMarker, FnMarkerAggr, FnResult, RuntimeMarker};
136 use crate::r#async::Runtime;
137
138 /// Runtime marker implementation for async runtime types.
139 impl<T: Runtime> RuntimeMarker for T {}
140
141 /// Marker trait for asynchronous functions.
142 ///
143 /// This trait extends `FnMarker` to specifically mark asynchronous
144 /// function types.
145 ///
146 /// # Examples
147 ///
148 /// ```rust,no_run
149 /// # #[cfg(feature = "async")]
150 /// # fn example() {
151 /// use cel_cxx::marker::{FnMarkerAsync, Async};
152 ///
153 /// fn async_function_example<F: FnMarkerAsync>() {
154 /// // This only works with async function markers
155 /// }
156 ///
157 /// // Async is an example of FnMarkerAsync
158 /// async_function_example::<Async>();
159 /// # }
160 /// ```
161 pub trait FnMarkerAsync: FnMarker {}
162
163 /// Marker type for asynchronous functions.
164 ///
165 /// This is a zero-sized type used to mark contexts that support
166 /// asynchronous function evaluation.
167 ///
168 /// # Examples
169 ///
170 /// ```rust,no_run
171 /// # #[cfg(feature = "async")]
172 /// # fn example() -> Result<(), cel_cxx::Error> {
173 /// use cel_cxx::{Env, marker::Async};
174 ///
175 /// // Create an async-capable environment
176 /// let env = Env::builder()
177 /// .force_async()
178 /// .build()?;
179 /// # Ok::<(), cel_cxx::Error>(())
180 /// # }
181 /// ```
182 #[allow(missing_debug_implementations)]
183 pub enum Async {}
184
185 /// Function marker implementation for async functions.
186 impl FnMarker for Async {}
187
188 /// Async function marker trait implementation.
189 impl FnMarkerAsync for Async {}
190
191 /// Aggregating sync with async yields async.
192 ///
193 /// When synchronous and asynchronous capabilities are combined,
194 /// the result supports asynchronous operations.
195 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
196 impl FnMarkerAggr<()> for Async {
197 type Output = Async;
198 }
199
200 /// Aggregating async with sync yields async.
201 ///
202 /// When asynchronous and synchronous capabilities are combined,
203 /// the result supports asynchronous operations.
204 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
205 impl FnMarkerAggr<Async> for () {
206 type Output = Async;
207 }
208
209 /// Aggregating async with async yields async.
210 ///
211 /// Combining two async contexts remains async.
212 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
213 impl FnMarkerAggr<Async> for Async {
214 type Output = Async;
215 }
216
217 /// Asynchronous function results.
218 ///
219 /// For asynchronous functions, the result type is wrapped in a BoxFuture.
220 /// This allows async functions to return futures that can be awaited.
221 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
222 impl<'a, T> FnResult<'a, T> for Async {
223 type Output = futures::future::BoxFuture<'a, T>;
224 }
225}
226
227/// Private sealed trait to prevent external implementations.
228///
229/// This module ensures that marker traits can only be implemented by types
230/// within this crate, providing type safety and preventing misuse.
231mod private {
232 #![allow(unused)]
233 use super::*;
234 #[cfg(feature = "async")]
235 use crate::r#async::Runtime;
236
237 /// Sealed trait to prevent external implementations.
238 ///
239 /// This trait is implemented only for types that are allowed to be
240 /// markers in the cel-cxx type system.
241 pub trait Sealed: 'static {}
242
243 /// Unit type can be a marker (represents sync operations).
244 impl Sealed for () {}
245
246 /// Async marker type can be a marker.
247 #[cfg(feature = "async")]
248 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
249 impl Sealed for Async {}
250
251 /// Runtime types can be runtime markers.
252 #[cfg(feature = "async")]
253 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
254 impl<T: Runtime> Sealed for T {}
255}
256
257#[cfg(test)]
258mod test {
259 #![allow(unused)]
260 #![allow(clippy::let_unit_value)]
261 use super::*;
262
263 fn test_fn_marker_aggregation<M1, M2>() -> <M1 as FnMarkerAggr<M2>>::Output
264 where
265 M1: FnMarker + FnMarkerAggr<M2>,
266 M2: FnMarker,
267 {
268 todo!()
269 }
270
271 fn test_eval_result<'a, M, T>() -> <M as FnResult<'a, T>>::Output
272 where
273 M: FnResult<'a, T> + FnMarker,
274 {
275 todo!()
276 }
277
278 fn t1() {
279 let x = test_fn_marker_aggregation::<(), ()>();
280 let v = test_eval_result::<(), i32>();
281
282 #[cfg(feature = "async")]
283 {
284 use crate::marker::Async;
285
286 let x = test_fn_marker_aggregation::<(), Async>();
287 let x = test_fn_marker_aggregation::<Async, ()>();
288 let x = test_fn_marker_aggregation::<Async, Async>();
289
290 let v = test_eval_result::<Async, i32>();
291 }
292 }
293}