#[macro_export]
macro_rules! ezrpc {
(
$(fn $fname:ident$(<$lf:lifetime>)?($(*$ss:ident,)? $($arg:ident: $type:ty),*) $(-> $ret:ty)? $([$n:expr])?;)*
) => {
#[macro_export]
macro_rules! init_service {
($trait:ty, $t:ty) => {
impl $t {
pub fn init_service(service: &$crate::MappedService<Self>) {
use $trait as Service;
$($crate::ezrpc!(@add service, Self, $fname $(= $n)?);)*
}
pub fn new_service(self) -> $crate::MappedService<Self> {
let service = $crate::MappedService::<Self>::new(self);
Self::init_service(&service);
service
}
}
};
}
pub use init_service;
#[allow(non_snake_case)]
pub trait Service: Send + Sync + Sized + 'static {
$($crate::ezrpc!{@serv ($fname, $(<$lf>)? $(*$ss,)? $($arg: $type),*) $(-> $ret)?})*
}
#[allow(non_snake_case)]
pub trait SessionMethod {
$($crate::ezrpc!{@decl ($fname, $(<$lf>)? $($arg: $type),*) $(-> $ret)?})*
}
#[allow(non_snake_case)]
impl SessionMethod for $crate::Session {
$($crate::ezrpc!{@call ($fname $(= $n)?, $(<$lf>)? $($arg: $type),*) $(-> $ret)?})*
}
};
(@method $fname:ident) => { stringify!($fname) };
(@method $fname:ident = $n:expr) => { $n };
(@add $service:ident, $Self:ty, $fname:ident) => { $service.add(stringify!($fname), <$Self as Service>::$fname); };
(@add $service:ident, $Self:ty, $fname:ident = $n:expr) => { $service.add($n, <$Self as Service>::$fname); };
(@serv ($m:ident, $(<$lf:lifetime>)? $(*$ss:ident,)? $($arg:ident: $type:ty),*)) => {
async fn $m$(<$lf>)?(&$($lf)? self, $($ss: $crate::ArcRpcContext,)? $($arg: $type),*) -> ::anyhow::Result<()>;
};
(@serv ($m:ident, $(<$lf:lifetime>)? $(*$ss:ident,)? $($arg:ident: $type:ty),*) -> $ret:ty) => {
async fn $m$(<$lf>)?(&$($lf)? self, $($ss: $crate::ArcRpcContext,)? $($arg: $type),*) -> ::anyhow::Result<$ret>;
};
(@decl ($m:ident, $(<$lf:lifetime>)? $($arg:ident: $type:ty),*)) => {
async fn $m$(<$lf>)?(self: &$($lf)? ::std::sync::Arc<Self>, $($arg: $type),*) -> ::anyhow::Result<()>;
};
(@decl ($m:ident, $(<$lf:lifetime>)? $($arg:ident: $type:ty),*) -> $ret:ty) => {
async fn $m$(<$lf>)?(self: &$($lf)? ::std::sync::Arc<Self>, $($arg: $type),*) -> ::anyhow::Result<$ret>;
};
(@call ($m:ident $(= $n:expr)?, $(<$lf:lifetime>)? $($arg:ident: $type:ty),*)) => {
#[inline]
async fn $m$(<$lf>)?(self: &$($lf)? ::std::sync::Arc<Self>, $($arg: $type),*) -> ::anyhow::Result<()> {
self.notify($crate::ezrpc!(@method $m $(= $n)?), ($($arg),*)).await
}
};
(@call ($m:ident $(= $n:expr)?, $(<$lf:lifetime>)? $($arg:ident: $type:ty),*) -> $ret:ty) => {
#[inline]
async fn $m$(<$lf>)?(self: &$($lf)? ::std::sync::Arc<Self>, $($arg: $type),*) -> ::anyhow::Result<$ret> {
self.request($crate::ezrpc!(@method $m $(= $n)?), ($($arg),*)).await
}
};
}