Skip to content

Commit

Permalink
Fix errors with generics when using the proc macro (#433)
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejhirsz authored Aug 18, 2021
1 parent c69e0dd commit 872a8d7
Showing 1 changed file with 26 additions and 19 deletions.
45 changes: 26 additions & 19 deletions proc-macros/src/new/render_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ impl RpcDescription {
}

fn render_into_rpc(&self) -> Result<TokenStream2, syn::Error> {
let jrps_error = self.jrps_server_item(quote! { types::Error });
let rpc_module = self.jrps_server_item(quote! { RpcModule });

let mut registered = HashSet::new();
Expand All @@ -62,6 +61,18 @@ impl RpcDescription {
}
};

/// Helper that will ignore results of `register_*` method calls, and panic
/// if there have been any errors in debug builds.
///
/// The debug assert is a safeguard should the contract that guarantees the method
/// names to never conflict in the macro be broken in the future.
fn handle_register_result(tokens: TokenStream2) -> TokenStream2 {
quote! {{
let res = #tokens;
debug_assert!(res.is_ok(), "RPC macro method names should never conflict, this is a bug, please report it.");
}}
}

let methods = self
.methods
.iter()
Expand All @@ -78,22 +89,22 @@ impl RpcDescription {
check_name(rpc_method_name.clone(), rust_method_name.span());

if method.signature.sig.asyncness.is_some() {
quote! {
handle_register_result(quote! {
rpc.register_async_method(#rpc_method_name, |params, context| {
let fut = async move {
#parsing
Ok(context.as_ref().#rust_method_name(#params_seq).await)
};
Box::pin(fut)
})?;
}
})
})
} else {
quote! {
handle_register_result(quote! {
rpc.register_method(#rpc_method_name, |params, context| {
#parsing
Ok(context.#rust_method_name(#params_seq))
})?;
}
})
})
}
})
.collect::<Vec<_>>();
Expand All @@ -116,12 +127,12 @@ impl RpcDescription {
check_name(rpc_sub_name.clone(), rust_method_name.span());
check_name(rpc_unsub_name.clone(), rust_method_name.span());

quote! {
handle_register_result(quote! {
rpc.register_subscription(#rpc_sub_name, #rpc_unsub_name, |params, sink, context| {
#parsing
Ok(context.as_ref().#rust_method_name(sink, #params_seq))
})?;
}
})
})
})
.collect::<Vec<_>>();

Expand All @@ -131,17 +142,13 @@ impl RpcDescription {
Ok(quote! {
#[doc = #doc_comment]
fn into_rpc(self) -> #rpc_module<Self> {
let inner = move || -> Result<#rpc_module<Self>, #jrps_error> {
let mut rpc = #rpc_module::new(self);

#(#errors)*
#(#methods)*
#(#subscriptions)*
let mut rpc = #rpc_module::new(self);

Ok(rpc)
};
#(#errors)*
#(#methods)*
#(#subscriptions)*

inner().expect("RPC macro method names should never conflict")
rpc
}
})
}
Expand Down

0 comments on commit 872a8d7

Please sign in to comment.