#[macro_export]
macro_rules! static_node {
(
$name:ident ( $request:ident , $client_cmd_tx:ident ) {
$(
$method:tt
[ $($flags:ident)|* , $access:ident , $methodparam:expr , $methodresult:expr ]
$(
{ $( ($signame:expr, $sigval:expr) ),* $(,)? }
)?
$( ( $param:ident : $ptype:ty ) )?
=> $body:block
)+
}
) => {
{
pub struct $name;
$crate::impl_static_node!(
$name ( &self, $request, $client_cmd_tx ) {
$(
$method
[ $($flags)|* , $access, $methodparam, $methodresult ]
$(
{ $( ($signame, $sigval) ),* }
)?
$( ( $param: $ptype) )?
=> $body
)+
}
);
$name
}
}
}
#[macro_export]
macro_rules! impl_static_node {
(
$type:ident ( & $self_ident:ident , $request:ident , $client_cmd_tx:ident ) {
$(
$method:tt
[ $($flags:ident)|* , $access:ident , $methodparam:expr , $methodresult:expr ]
$(
{ $( ($signame:expr, $sigval:expr) ),* $(,)? }
)?
$( ( $param:ident : $ptype:ty ) )?
=> $body:block
)+
}
) => {
#[async_trait::async_trait]
impl $crate::clientnode::StaticNode for $type {
fn methods(&self) -> &'static [$crate::clientnode::MetaMethod] {
const METHODS: &[$crate::clientnode::MetaMethod] =
&[
$(
$crate::clientnode::MetaMethod::new_static(
$method,
$crate::clientnode::Flags::from_bits_retain(0 $(| $crate::clientnode::Flags::$flags.bits() )* ),
$crate::clientnode::AccessLevel::$access,
$methodparam,
$methodresult,
&[
$($(($signame, $sigval)),*)?
],
"",
)
),+
];
METHODS
}
async fn process_request(
&$self_ident,
$request: $crate::shvrpc::rpcmessage::RpcMessage,
$client_cmd_tx: $crate::ClientCommandSender,
) -> Option<$crate::clientnode::RequestResult>
{
use $crate::shvrpc::RpcMessageMetaTags;
match $request.method() {
$(
Some($method) => {
$crate::method_handler!(
$( ($param : $ptype) )?
$method @ $request @ $body
)
}
)+
_ => Some(Err($crate::clientnode::RpcError::new(
$crate::clientnode::RpcErrorCode::MethodNotFound,
format!("Invalid method: {:?}", $request.method())
))),
}
}
}
};
}
#[macro_export]
macro_rules! method_handler {
(($param:ident : $type:ty) $method:tt @ $request:ident @ $body:block) => {
{
let request_param = $request.param().unwrap_or_default();
match <$type>::try_from(request_param) {
Ok($param) => $body,
Err(err) => Some(Err($crate::clientnode::RpcError::new(
$crate::clientnode::RpcErrorCode::InvalidParam,
format!("Wrong parameter for `{method}`: {err}",
method = $method
))))
}
}
};
($method:tt @ $request:ident @ $body:block) => {
$body
};
}
#[macro_export]
macro_rules! count {
() => (0usize);
( $x:tt $($xs:tt)* ) => (1usize + $crate::count!($($xs)*));
}