cel_cxx/async/
mod.rs

1//! Asynchronous runtime support for CEL.
2//!
3//! This module provides support for asynchronous evaluation of CEL expressions
4//! using the [async-std](https://github.com/async-rs/async-std) or
5//! [tokio](https://github.com/tokio-rs/tokio) runtimes.
6//!
7//! # Features
8//! - `async-std`: Enables asynchronous evaluation of CEL expressions using
9//!   [async-std](https://github.com/async-rs/async-std).
10//! - `tokio`: Enables asynchronous evaluation of CEL expressions using
11//!   [tokio](https://github.com/tokio-rs/tokio).
12//!
13
14use async_scoped::spawner::{Blocker, FuncSpawner, Spawner};
15use futures::Future;
16
17pub(crate) mod abort;
18
19/// Runtime trait for CEL asynchronous runtime.
20pub trait Runtime: 'static {
21    /// Scoped spawner for CEL asynchronous runtime.
22    type ScopedSpawner: Spawner<()>
23        + FuncSpawner<(), SpawnHandle = <Self::ScopedSpawner as Spawner<()>>::SpawnHandle>
24        + Blocker
25        + Default
26        + Send
27        + Sync
28        + 'static;
29
30    /// Blocking runner for CEL asynchronous runtime.
31    type BlockingRunner: BlockingRunner;
32}
33
34/// Blocking runner trait for CEL asynchronous runtime.
35pub trait BlockingRunner: 'static {
36    /// Block on a future.
37    fn block_on<F: Future>(fut: F) -> F::Output;
38}
39
40/// Tokio runtime for CEL asynchronous runtime.
41#[cfg(feature = "tokio")]
42#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
43#[allow(missing_debug_implementations)]
44pub enum Tokio {}
45
46/// Tokio runtime implementation.
47#[cfg(feature = "tokio")]
48#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
49pub mod tokio {
50    #![allow(missing_debug_implementations)]
51    use super::*;
52
53    impl Runtime for Tokio {
54        type ScopedSpawner = async_scoped::spawner::use_tokio::Tokio;
55        type BlockingRunner = TokioBlockingRunner;
56    }
57
58    /// Tokio blocking runner for CEL asynchronous runtime.
59    pub struct TokioBlockingRunner;
60    impl BlockingRunner for TokioBlockingRunner {
61        fn block_on<F: Future>(fut: F) -> F::Output {
62            ::tokio::runtime::Handle::current().block_on(fut)
63        }
64    }
65}
66
67/// Async-std runtime for CEL asynchronous runtime.
68#[cfg(feature = "async-std")]
69#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
70#[allow(missing_debug_implementations)]
71pub enum AsyncStd {}
72
73/// Async-std runtime implementation.
74#[cfg(feature = "async-std")]
75#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
76pub mod async_std {
77    #![allow(missing_debug_implementations)]
78    use super::*;
79
80    impl Runtime for AsyncStd {
81        type ScopedSpawner = async_scoped::spawner::use_async_std::AsyncStd;
82        type BlockingRunner = AsyncStdBlockingRunner;
83    }
84
85    /// Async-std blocking runner for CEL asynchronous runtime.
86    pub struct AsyncStdBlockingRunner;
87    impl BlockingRunner for AsyncStdBlockingRunner {
88        fn block_on<F: Future>(fut: F) -> F::Output {
89            ::async_std::task::block_on(fut)
90        }
91    }
92}
93
94/// Smol runtime for CEL asynchronous runtime.
95#[cfg(feature = "smol")]
96#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
97#[allow(missing_debug_implementations)]
98pub enum Smol {}
99
100/// Smol runtime for CEL asynchronous runtime.
101#[cfg(feature = "smol")]
102#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
103pub mod smol {
104    #![allow(missing_debug_implementations)]
105    use super::*;
106
107    impl Runtime for Smol {
108        type ScopedSpawner = SmolScopedSpawner;
109        type BlockingRunner = SmolBlockingRunner;
110    }
111
112    /// Smol scoped spawner for CEL asynchronous runtime.
113    #[derive(Default)]
114    #[allow(missing_debug_implementations)]
115    pub struct SmolScopedSpawner;
116    unsafe impl<T: Send + 'static> Spawner<T> for SmolScopedSpawner {
117        type FutureOutput = T;
118        type SpawnHandle = ::smol::Task<T>;
119
120        fn spawn<F: Future<Output = T> + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
121            ::smol::spawn(f)
122        }
123    }
124    unsafe impl<T: Send + 'static> FuncSpawner<T> for SmolScopedSpawner {
125        type FutureOutput = T;
126        type SpawnHandle = ::smol::Task<T>;
127
128        fn spawn_func<F: FnOnce() -> T + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
129            ::smol::unblock(f)
130        }
131    }
132    unsafe impl Blocker for SmolScopedSpawner {
133        fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
134            ::smol::block_on(f)
135        }
136    }
137
138    /// Smol blocking runner for CEL asynchronous runtime.
139    pub struct SmolBlockingRunner;
140    impl BlockingRunner for SmolBlockingRunner {
141        fn block_on<F: Future>(fut: F) -> F::Output {
142            ::smol::block_on(fut)
143        }
144    }
145}