#[macro_export]
macro_rules! ghost_chan {
( @inner_tx
$(#[$ameta:meta])*
($($avis:tt)*) chan $aname:ident<$aerr:ty> {
$(
$(#[$rmeta:meta])* fn $rname:ident ( $($pname:ident: $pty:ty),* $(,)? ) -> $rret:ty;
)*
}
) => {
$crate::dependencies::paste::item! {
$crate::ghost_chan! { @inner
($($ameta)*) ($($avis)*) $aname $aerr [$(
($($rmeta)*) $rname [< $rname:camel >] $rret [$(
$pname $pty
)*]
)*]
}
}
};
( @inner
($($ameta:meta)*) ($($avis:tt)*) $aname:ident $aerr:ty [$(
($($rmeta:meta)*) $rname:ident $rnamec:ident $rret:ty [$(
$pname:ident $pty:ty
)*]
)*]
) => {
$crate::dependencies::paste::item! {
$($avis)* type [< $aname Result >] <T> = ::std::result::Result<T, $aerr>;
$($avis)* type [< $aname Future >] <T> = $crate::dependencies::must_future::MustBoxFuture<'static, [< $aname Result >] <T> >;
$($avis)* type [< $aname HandlerResult >] <T> = ::std::result::Result<[< $aname Future >] <T>, $aerr>;
}
$crate::ghost_chan! { @inner_protocol
($($ameta)*) ($($avis)*) $aname $aerr [$(
($($rmeta)*) $rname $rnamec $rret [$(
$pname $pty
)*]
)*]
}
$crate::ghost_chan! { @inner_send_trait
($($ameta)*) ($($avis)*) $aname $aerr [$(
($($rmeta)*) $rname $rnamec $rret [$(
$pname $pty
)*]
)*]
}
$crate::ghost_chan! { @inner_handler_trait
($($ameta)*) ($($avis)*) $aname $aerr [$(
($($rmeta)*) $rname $rnamec $rret [$(
$pname $pty
)*]
)*]
}
};
( @inner_protocol
($($ameta:meta)*) ($($avis:tt)*) $aname:ident $aerr:ty [$(
($($rmeta:meta)*) $rname:ident $rnamec:ident $rret:ty [$(
$pname:ident $pty:ty
)*]
)*]
) => {
$crate::dependencies::paste::item! {
$(#[$ameta])*
$($avis)* enum $aname {
$(
$(#[$rmeta])*
$rnamec {
span: $crate::dependencies::tracing::Span,
respond: $crate::GhostRespond<
[< $aname HandlerResult >] <$rret>,
>,
$(
$pname: $pty,
)*
},
)*
}
impl $crate::GhostEvent for $aname {}
impl<H: [< $aname Handler >]> $crate::GhostDispatch<H> for $aname {
fn ghost_actor_dispatch(self, h: &mut H) {
match self {
$(
$aname::$rnamec { span: _span, respond, $($pname,)* } => {
respond.respond(h.[< handle_ $rname >]($($pname,)*));
}
)*
}
}
}
impl ::std::fmt::Debug for $aname {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match self {
$(
$aname :: $rnamec { .. } => {
write!(
f,
"{}::{} {{ .. }}",
stringify!($aname),
stringify!($rnamec),
)
}
)*
}
}
}
}
};
( @inner_send_trait
($($ameta:meta)*) ($($avis:tt)*) $aname:ident $aerr:ty [$(
($($rmeta:meta)*) $rname:ident $rnamec:ident $rret:ty [$(
$pname:ident $pty:ty
)*]
)*]
) => {
$crate::dependencies::paste::item! {
$(#[$ameta])*
$($avis)* trait [< $aname Sender >]: $crate::GhostChannelSender<$aname> {
$(
$(#[$rmeta])*
fn $rname(&self, $($pname: $pty),*) -> [< $aname Future >] <$rret> {
let (s, r) = $crate::dependencies::futures::channel::oneshot::channel();
let t = $aname::$rnamec {
span: $crate::dependencies::tracing::Span::none(),
respond: $crate::GhostRespond::new(
s,
concat!(stringify!($rname), "_respond"),
),
$($pname: $pname,)*
};
let send_fut = self.ghost_actor_channel_send(t);
$crate::dependencies::must_future::MustBoxFuture::new(async move {
send_fut.await?;
let (r, _span) = r.await.map_err($crate::GhostError::from)?;
r?.await
})
}
)*
}
impl<S: $crate::GhostChannelSender<$aname>> [< $aname Sender >] for S {}
}
};
( @inner_handler_trait
($($ameta:meta)*) ($($avis:tt)*) $aname:ident $aerr:ty [$(
($($rmeta:meta)*) $rname:ident $rnamec:ident $rret:ty [$(
$pname:ident $pty:ty
)*]
)*]
) => {
$crate::dependencies::paste::item! {
$(#[$ameta])*
$($avis)* trait [< $aname Handler >]: $crate::GhostHandler<$aname> {
$(
$(#[$rmeta])*
fn [< handle_ $rname >] (
&mut self, $($pname: $pty,)*
) -> [< $aname HandlerResult >]<$rret>;
)*
}
}
};
(
$(#[$ameta:meta])* pub ( $($avis:tt)* ) chan $($rest:tt)*
) => {
$crate::ghost_chan! { @inner_tx
$(#[$ameta])* (pub($($avis)*)) chan $($rest)*
}
};
(
$(#[$ameta:meta])* pub chan $($rest:tt)*
) => {
$crate::ghost_chan! { @inner_tx
$(#[$ameta])* (pub) chan $($rest)*
}
};
(
$(#[$ameta:meta])* chan $($rest:tt)*
) => {
$crate::ghost_chan! { @inner_tx
$(#[$ameta])* () chan $($rest)*
}
};
}