#[doc(hidden)]
#[macro_export]
macro_rules! __make_tuple_cons {
() => {
()
};
(mut $first:ident, $($rest:tt)* ) => {
(mut $first, $crate::__make_tuple_cons!($($rest)*))
};
($first:ty, $($rest:tt)* ) => {
($first, $crate::__make_tuple_cons!($($rest)*))
};
}
#[macro_export]
macro_rules! execute {
(
store: [
$($data_type:ty),* $(,)?
],
actors: [
$($actor_type:ty $(: $init_context:expr )? ),* $(,)?
],
validation: async |$(mut $arg_pat:ident : $arg_ty:ty),* $(,)?| $validation_body:block $(,)?
) => {{
struct Validator<'a> {
store_request: $crate::__make_tuple_cons!($($arg_ty,)*),
complete: $crate::__exports::futures::channel::oneshot::Sender<()>,
_phantom: core::marker::PhantomData<&'a ()>,
}
impl<'a> $crate::__exports::veecle_os_runtime::Actor<'a> for Validator<'a> {
type StoreRequest = $crate::__make_tuple_cons!($($arg_ty,)*);
type InitContext = $crate::__exports::futures::channel::oneshot::Sender<()>;
type Error = core::convert::Infallible;
fn new(store_request: Self::StoreRequest, complete: Self::InitContext) -> Self {
Self {
store_request,
complete,
_phantom: core::marker::PhantomData
}
}
async fn run(self) -> Result<core::convert::Infallible, Self::Error> {
let $crate::__make_tuple_cons!($(mut $arg_pat,)*) = self.store_request;
$validation_body;
self.complete.send(()).unwrap();
core::future::pending().await
}
}
async {
let (complete_tx, complete_rx) =
$crate::__exports::futures::channel::oneshot::channel::<()>();
let executor = core::pin::pin!(
$crate::__exports::veecle_os_runtime::execute! {
store: [ $($data_type,)* ],
actors: [
$($actor_type $(: $init_context)? ,)*
Validator: complete_tx,
],
}
);
$crate::__exports::futures::future::select(executor, complete_rx).await;
}
}};
(
store: [
$($data_type:ty),* $(,)?
],
actors: [
$($actor_type:ty $(: $init_context:expr )? ),* $(,)?
],
validation: async || $validation_body:block $(,)?
) => {{
$crate::execute!(
store: [
$($data_type),*
],
actors: [
$($actor_type $(: $init_context)? ),*
],
validation: async | | $validation_body
)
}};
}
#[cfg(test)]
mod tests {
#[veecle_os_runtime::actor]
async fn contextual_actor<T: core::fmt::Debug>(
#[init_context] _context: T,
) -> core::convert::Infallible {
std::future::pending().await
}
#[test]
fn local_context() {
let local = vec![1];
futures::executor::block_on(crate::execute! {
store: [],
actors: [
ContextualActor<_>: &local,
],
validation: async || {}
});
dbg!(&local);
}
}