Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proc mac support map param #544

Merged

Conversation

DefinitelyNotHilbert
Copy link
Contributor

@DefinitelyNotHilbert DefinitelyNotHilbert commented Oct 29, 2021

This is my MR for #538.

  • Added param_format parameter to the method and subscription attributes. It takes a string parameter, "map"to make the macro generate a function that sends the parameters as a map, everything else will fall back to the default "array". I'm not too happy with the fact that it is a string, so if anybody has an alternative, be my friend :)

  • Updated render_method and render_sub to generate the necessary code. There's an additional function that extracts the parameter names from the function signature

I wasn't sure how / if you test your macros, so I didn't do anything related to unit test, but I can confirm that the code is generated correctly and works, judging from how it interacts with json_rpc APIs.

Looking forward to your comments :)

polkadot address: 13bL3pENnNbFKYD6GPjibJHv4jUTnwNPoVjp9YpU4oJfFefS

Copy link
Member

@niklasad1 niklasad1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great,

please add a test in jsonrpsee/proc-macros/tests/ui/correct/* for this, to test that it actually works with the servers too.

you can look in jsonrpsee/proc-macros/tests/ui/correct/basic how to do it so up to you whether to add a new file for this or in existing one...

- Addressed @niklasad1's suggestion to use an Option instead of just
defaulting to "array".
- Use enum for param format.
- Extract parsing logic into separate function.
- Add ui test.
@DefinitelyNotHilbert
Copy link
Contributor Author

great,

please add a test in jsonrpsee/proc-macros/tests/ui/correct/* for this, to test that it actually works with the servers too.

you can look in jsonrpsee/proc-macros/tests/ui/correct/basic how to do it so up to you whether to add a new file for this or in existing one...

I've added a test case in the spirit of basic.rs but I'm not 100% that it's exactly what you want.

Copy link
Member

@niklasad1 niklasad1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice work, thank you

LGTM

@niklasad1
Copy link
Member

@DefinitelyNotHilbert just run cargo fmt --all and push it then the CI should be happy

Copy link
Contributor

@dvdplm dvdplm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, tyvm.

Some docs here about the new attr would be good.

proc-macros/tests/ui/correct/param_format.rs Outdated Show resolved Hide resolved
proc-macros/src/render_client.rs Outdated Show resolved Hide resolved
proc-macros/src/attributes.rs Outdated Show resolved Hide resolved
proc-macros/src/render_client.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@maciejhirsz maciejhirsz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to be a bit more pedantic here, sorry :D. Added suggestions on how to turn the "array"|"map" into array|map and one other nit.

In general I think that since this is a binary option, and it's always going to be a binary option, we should probably use a flag argument. So instead of:

#[method(name = "foo", param_kind = map)]

You'd just write:

#[method(name = "foo", serialize_as_map)]

Or some such. I reckon that's easier to grok since you don't have to look up possible values, and code should also be easier since there are fewer error conditions.

Comment on lines 199 to 205
pub(crate) fn parse_param_kind(arg: Result<Argument, MissingArgument>) -> ParamKind {
match optional(arg, Argument::string).unwrap().as_deref() {
None | Some("array") => ParamKind::Array,
Some("map") => ParamKind::Map,
err => panic!("param_kind must be either `map` or `array`, got {:?}", err),
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should return an error here, unwrap is going to throw away span information on invalid parse of the argument value. Instead of a string we could parse to raw Argument::value using syn::Ident so you can skip quotes, plus then you have the span to use to emit an error instead of a panic.

No guarantees that this compiles:

Suggested change
pub(crate) fn parse_param_kind(arg: Result<Argument, MissingArgument>) -> ParamKind {
match optional(arg, Argument::string).unwrap().as_deref() {
None | Some("array") => ParamKind::Array,
Some("map") => ParamKind::Map,
err => panic!("param_kind must be either `map` or `array`, got {:?}", err),
}
}
pub(crate) fn parse_param_kind(arg: Result<Argument, MissingArgument>) -> syn::Result<ParamKind> {
let kind: Option<syn::Ident> = optional(arg, Argument::value)?;
match kind {
None => Ok(ParamKind::Array),
Some(ident) if ident == "array" => Ok(ParamKind::Array),
Some(ident) if ident == "map" => Ok(ParamKind::Map),
Some(ident) => Err(Error::new(ident.span(), "param_kind must be either `map` or `array`")),
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figure that this won't be necessary if we go with your suggestion of turning parma_kind into a flag, because we can get rid of the function.

Personally, I prefer the more verbose version (that's why I've implemented it in this way), but I completely get your point. Since this is obviously not my library, I'm happy to turn it into a flag if you want, I just care about the feature as a whole.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is only if we want to keep the verbose variant.

I don't have a super strong opinion on this, and don't necessarily want to turn it into a bike shed. We can still change the syntax of it later before 0.5 is stabilized.

proc-macros/src/render_client.rs Outdated Show resolved Hide resolved
proc-macros/tests/ui/correct/param_kind.rs Outdated Show resolved Hide resolved
Apply @maciejhirsz formatting suggestion.

Co-authored-by: Maciej Hirsz <1096222+maciejhirsz@users.noreply.github.com>
- make parameter encoding DRY
- remove strings from param_kind
- return result from parse_param_kind
Copy link
Contributor

@maciejhirsz maciejhirsz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maciejhirsz maciejhirsz merged commit ff3337b into paritytech:master Nov 3, 2021
@dvdplm
Copy link
Contributor

dvdplm commented Nov 3, 2021

/tip medium

@substrate-tip-bot
Copy link

Please fix the following problems before calling the tip bot again:

  • Contributor did not properly post their Polkadot or Kusama address. Make sure the pull request has: "{network} address: {address}".

@dvdplm
Copy link
Contributor

dvdplm commented Nov 3, 2021

@DefinitelyNotHilbert Thank you for your work here. Please post a comment with a polkadot address to receive your tip. :)

@DefinitelyNotHilbert
Copy link
Contributor Author

polkadot address: 13bL3pENnNbFKYD6GPjibJHv4jUTnwNPoVjp9YpU4oJfFefS

@dvdplm
Copy link
Contributor

dvdplm commented Nov 4, 2021

/tip medium

@substrate-tip-bot
Copy link

Please fix the following problems before calling the tip bot again:

  • Contributor did not properly post their Polkadot or Kusama address. Make sure the pull request has: "{network} address: {address}".

@dvdplm
Copy link
Contributor

dvdplm commented Nov 4, 2021

Hmm, stupid bot. We'll get this sorted.

@shawntabrizi
Copy link

/tip medium

@substrate-tip-bot
Copy link

A medium tip was successfully submitted for DefinitelyNotHilbert (13bL3pENnNbFKYD6GPjibJHv4jUTnwNPoVjp9YpU4oJfFefS on polkadot).

https://polkadot.js.org/apps/#/treasury/tips

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants