diff --git a/proc-macros/src/attributes.rs b/proc-macros/src/attributes.rs index ba28bf3718..02da827efa 100644 --- a/proc-macros/src/attributes.rs +++ b/proc-macros/src/attributes.rs @@ -53,6 +53,10 @@ pub struct Resource { pub value: syn::LitInt, } +pub struct Aliases { + pub list: Punctuated, +} + impl Parse for Argument { fn parse(input: ParseStream) -> syn::Result { let label = input.parse()?; @@ -87,6 +91,18 @@ impl Parse for Resource { } } +impl Parse for Aliases { + fn parse(input: ParseStream) -> syn::Result { + let content; + + syn::bracketed!(content in input); + + let list = content.parse_terminated(Parse::parse)?; + + Ok(Aliases { list }) + } +} + fn parenthesized(input: ParseStream) -> syn::Result> { let content; diff --git a/proc-macros/src/render_server.rs b/proc-macros/src/render_server.rs index 962aa4bb00..86b96cb757 100644 --- a/proc-macros/src/render_server.rs +++ b/proc-macros/src/render_server.rs @@ -205,8 +205,7 @@ impl RpcDescription { .aliases .iter() .map(|alias| { - let alias = alias.trim().to_string(); - check_name(&alias, rust_method_name.span()); + check_name(alias, rust_method_name.span()); handle_register_result(quote! { rpc.register_alias(#alias, #rpc_name) }) @@ -229,8 +228,7 @@ impl RpcDescription { .aliases .iter() .map(|alias| { - let alias = alias.trim().to_string(); - check_name(&alias, rust_method_name.span()); + check_name(alias, rust_method_name.span()); handle_register_result(quote! { rpc.register_alias(#alias, #sub_name) }) @@ -240,8 +238,7 @@ impl RpcDescription { .unsubscribe_aliases .iter() .map(|alias| { - let alias = alias.trim().to_string(); - check_name(&alias, rust_method_name.span()); + check_name(alias, rust_method_name.span()); handle_register_result(quote! { rpc.register_alias(#alias, #unsub_name) }) diff --git a/proc-macros/src/rpc_macro.rs b/proc-macros/src/rpc_macro.rs index 1ae2f5f05e..be251cae00 100644 --- a/proc-macros/src/rpc_macro.rs +++ b/proc-macros/src/rpc_macro.rs @@ -27,12 +27,13 @@ //! Declaration of the JSON RPC generator procedural macros. use crate::{ - attributes::{optional, parse_param_kind, Argument, AttributeMeta, MissingArgument, ParamKind, Resource}, + attributes::{optional, parse_param_kind, Aliases, Argument, AttributeMeta, MissingArgument, ParamKind, Resource}, helpers::extract_doc_comments, }; use proc_macro2::TokenStream as TokenStream2; use quote::quote; +use std::borrow::Cow; use syn::spanned::Spanned; use syn::{punctuated::Punctuated, Attribute, Token}; @@ -276,32 +277,25 @@ impl RpcDescription { /// Examples: /// For namespace `foo` and method `makeSpam`, result will be `foo_makeSpam`. /// For no namespace and method `makeSpam` it will be just `makeSpam. - pub(crate) fn rpc_identifier(&self, method: &str) -> String { + pub(crate) fn rpc_identifier<'a>(&self, method: &'a str) -> Cow<'a, str> { if let Some(ns) = &self.namespace { - format!("{}_{}", ns, method.trim()) + format!("{}_{}", ns, method).into() } else { - method.to_string() + Cow::Borrowed(method) } } } fn parse_aliases(arg: Result) -> syn::Result> { - let aliases = optional(arg, Argument::string)?; + let aliases = optional(arg, Argument::value::)?; - Ok(aliases.map(|a| a.split(',').map(Into::into).collect()).unwrap_or_default()) + Ok(aliases.map(|a| a.list.into_iter().map(|lit| lit.value()).collect()).unwrap_or_default()) } fn find_attr<'a>(attrs: &'a [Attribute], ident: &str) -> Option<&'a Attribute> { attrs.iter().find(|a| a.path.is_ident(ident)) } -fn build_unsubscribe_method(existing_method: &str) -> String { - let method = existing_method.trim(); - let mut new_method = String::from("unsubscribe"); - if method.starts_with("subscribe") { - new_method.extend(method.chars().skip(9)); - } else { - new_method.push_str(method); - } - new_method +fn build_unsubscribe_method(method: &str) -> String { + format!("unsubscribe{}", method.strip_prefix("subscribe").unwrap_or(method)) } diff --git a/proc-macros/tests/ui/correct/alias_doesnt_use_namespace.rs b/proc-macros/tests/ui/correct/alias_doesnt_use_namespace.rs index 5e4c203001..5ba32df63e 100644 --- a/proc-macros/tests/ui/correct/alias_doesnt_use_namespace.rs +++ b/proc-macros/tests/ui/correct/alias_doesnt_use_namespace.rs @@ -3,10 +3,10 @@ use jsonrpsee::{proc_macros::rpc, types::RpcResult}; #[rpc(client, server, namespace = "myapi")] pub trait Rpc { /// Alias doesn't use the namespace so not duplicated. - #[method(name = "getTemp", aliases = "getTemp")] + #[method(name = "getTemp", aliases = ["getTemp"])] async fn async_method(&self, param_a: u8, param_b: String) -> RpcResult; - #[subscription(name = "getFood", item = String, aliases = "getFood", unsubscribe_aliases = "unsubscribegetFood")] + #[subscription(name = "getFood", item = String, aliases = ["getFood"], unsubscribe_aliases = ["unsubscribegetFood"])] fn sub(&self) -> RpcResult<()>; } diff --git a/proc-macros/tests/ui/correct/basic.rs b/proc-macros/tests/ui/correct/basic.rs index 07a6e99a40..c8052ce288 100644 --- a/proc-macros/tests/ui/correct/basic.rs +++ b/proc-macros/tests/ui/correct/basic.rs @@ -11,7 +11,7 @@ use std::net::SocketAddr; #[rpc(client, server, namespace = "foo")] pub trait Rpc { - #[method(name = "foo", aliases = "fooAlias, Other")] + #[method(name = "foo", aliases = ["fooAlias", "Other"])] async fn async_method(&self, param_a: u8, param_b: String) -> RpcResult; #[method(name = "optional_params")] @@ -29,7 +29,7 @@ pub trait Rpc { #[subscription(name = "sub", item = String)] fn sub(&self) -> RpcResult<()>; - #[subscription(name = "echo", aliases = "ECHO", item = u32, unsubscribe_aliases = "NotInterested, listenNoMore")] + #[subscription(name = "echo", aliases = ["ECHO"], item = u32, unsubscribe_aliases = ["NotInterested", "listenNoMore"])] fn sub_with_params(&self, val: u32) -> RpcResult<()>; } diff --git a/proc-macros/tests/ui/correct/parse_angle_brackets.rs b/proc-macros/tests/ui/correct/parse_angle_brackets.rs index 783f8df756..037e86c155 100644 --- a/proc-macros/tests/ui/correct/parse_angle_brackets.rs +++ b/proc-macros/tests/ui/correct/parse_angle_brackets.rs @@ -5,12 +5,12 @@ fn main() { pub trait Rpc { #[subscription( name = "submitAndWatchExtrinsic", - aliases = "author_extrinsicUpdate", - unsubscribe_aliases = "author_unwatchExtrinsic", + aliases = ["author_extrinsicUpdate"], + unsubscribe_aliases = ["author_unwatchExtrinsic"], // Arguments are being parsed the nearest comma, // angle braces need to be accounted for manually. item = TransactionStatus, )] fn dummy_subscription(&self) -> RpcResult<()>; } -} \ No newline at end of file +} diff --git a/proc-macros/tests/ui/incorrect/rpc/rpc_conflicting_alias.rs b/proc-macros/tests/ui/incorrect/rpc/rpc_conflicting_alias.rs index 00ed6b9b9e..3ba041a144 100644 --- a/proc-macros/tests/ui/incorrect/rpc/rpc_conflicting_alias.rs +++ b/proc-macros/tests/ui/incorrect/rpc/rpc_conflicting_alias.rs @@ -2,7 +2,7 @@ use jsonrpsee::proc_macros::rpc; use jsonrpsee::types::RpcResult; #[rpc(client, server)] pub trait DuplicatedAlias { - #[method(name = "foo", aliases = "foo_dup, foo_dup")] + #[method(name = "foo", aliases = ["foo_dup", "foo_dup"])] async fn async_method(&self) -> RpcResult; } diff --git a/proc-macros/tests/ui/incorrect/sub/sub_conflicting_alias.rs b/proc-macros/tests/ui/incorrect/sub/sub_conflicting_alias.rs index 595c792bff..993063c51a 100644 --- a/proc-macros/tests/ui/incorrect/sub/sub_conflicting_alias.rs +++ b/proc-macros/tests/ui/incorrect/sub/sub_conflicting_alias.rs @@ -2,7 +2,7 @@ use jsonrpsee::{proc_macros::rpc, types::RpcResult}; #[rpc(client, server)] pub trait DuplicatedSubAlias { - #[subscription(name = "alias", item = String, aliases = "hello_is_goodbye", unsubscribe_aliases = "hello_is_goodbye")] + #[subscription(name = "alias", item = String, aliases = ["hello_is_goodbye"], unsubscribe_aliases = ["hello_is_goodbye"])] fn async_method(&self) -> RpcResult<()>; } diff --git a/tests/tests/proc_macros.rs b/tests/tests/proc_macros.rs index 1fdbb9d4ab..84f9a313ec 100644 --- a/tests/tests/proc_macros.rs +++ b/tests/tests/proc_macros.rs @@ -49,7 +49,7 @@ mod rpc_impl { #[subscription(name = "sub", item = String)] fn sub(&self) -> RpcResult<()>; - #[subscription(name = "echo", aliases = "alias_echo", item = u32)] + #[subscription(name = "echo", aliases = ["alias_echo"], item = u32)] fn sub_with_params(&self, val: u32) -> RpcResult<()>; #[method(name = "params")]