macro_rules! crpc {
($(#[$outer:meta])*
fn [$mod:path] $f:ident/$method_id:literal(&mut $self:ident $(, $v:ident: $t:ty)*)
-> Result<$rt:ty>
$marshal:expr; $extract1:expr ) => {
crpc!(
$(#[$outer])*
fn [$mod] $f/$method_id(&mut self $(, $v: $t)*)
-> Result<$rt> -> Result<$rt>
$marshal;
$extract1;
|r| Ok(r));
};
($(#[$outer:meta])*
fn [$mod:path] $f:ident/$method_id:literal(&mut $self:ident $(, $v:ident: $t:ty)*)
-> Result<$irt:ty> -> Result<$rt:ty>
$marshal:expr; $extract1:expr; $extract2:expr ) => {
$(#[$outer])*
pub fn $f(&mut $self $(, $v: $t)*) -> Result<$rt> {
log::trace!("{}::{}", stringify!($mod), stringify!($f));
use $mod as m;
paste::paste! {
use m::[< $f _params >] as params;
use m::[< $f _results >] as results;
};
let mut message
= message::TypedBuilder::<params::Owned>::new_default();
let root: params::Builder = message.init_root();
let result: Result<()> = $marshal(root);
result?;
let message = message::TypedReader::from(message);
let extract1: Box<dyn FnOnce(
std::sync::Arc<std::sync::Mutex<crate::capnp_relay::CapnProtoRelay>>,
&mut crate::CapTable, results::Reader)
-> Result<$irt> + Send + Sync>
= Box::new($extract1);
let f = |relay: std::sync::Arc<std::sync::Mutex<crate::capnp_relay::CapnProtoRelay>>,
cap_table: &mut crate::CapTable,
response: capability::Response<any_pointer::Owned>|
-> Result<Box<dyn Any + Send + Sync>>
{
let response: results::Reader = response.get()?.get_as()?;
Ok(extract1(relay, cap_table, response).map(|r| {
Box::new(r) as Box<dyn std::any::Any + Send + Sync>
})?)
};
let relay = $self.relay.lock().unwrap();
let handle = relay
.send_rpc($self.cap.clone(),
<m::Client as HasTypeId>::TYPE_ID,
$method_id,
message.into_inner(),
f)?;
drop(relay);
let response = CapnProtoRelay::await_reply(handle)?;
let r: $irt = *response.downcast().unwrap();
let extract2: Box<dyn FnOnce($irt) -> Result<$rt>>
= Box::new($extract2);
let r: Result<$rt> = extract2(r);
Ok(r?)
}
};
}