Closed dtolnay closed 5 years ago
This feels like it'd be better as a PR to serde; having it in the docs at serde.rs would make it more discoverable and protecting it under serde's duplicate field and other validations seems to be a friendlier API. would you be opposed to this coming in a PR there?
Also then it is good to have prefix
and suffix
attribute for flatten
:
struct X {
#[serde(flatten(prefix = "Embed", suffix = "Field"))]
a,
}
I would not accept this as a PR to Serde. I don't think this pattern is sufficiently ubiquitous to justify a new attribute in serde_derive.
An attribute macro that expands to rename attributes would have just as much validation.
@dtolnay I'm currently looking at this. I was thinking of creating the #[serde(rename = "prefix_fieldname")]
attributes using quote! {}
and then inserting those in the AST tree. Right now I'm a bit stuck as it doesn't seem possible to create a new Attribute
which I would then insert.
Do you have any suggestions?
I would recommend using parse_quote to make attributes: https://docs.rs/syn/0.15/syn/macro.parse_quote.html
Thanks! That got me on the right track!
On Wed 19. Jun 2019 at 20:06, David Tolnay notifications@github.com wrote:
I would recommend using parse_quote to make attributes: https://docs.rs/syn/0.15/syn/macro.parse_quote.html
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/dtolnay/request-for-implementation/issues/19?email_source=notifications&email_token=AAQGYEVYAVJQP7ZDFBOGSLDP3JYRHA5CNFSM4GRPAGM2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYCWBRQ#issuecomment-503668934, or mute the thread https://github.com/notifications/unsubscribe-auth/AAQGYESNWV5NDZY3YXJHVW3P3JYRHANCNFSM4GRPAGMQ .
-- Sent from Gmail Mobile
@dtolnay I've got a repo up now https://github.com/jonathan-s/serde_prefix I would be very grateful if you had a look at it. I still need to add some documentation for how it should be used.
But in short #[prefix_all("test_")]
can be used for structs and enums to rename attributes. Inside the box it uses #[serde(rename = "test_attributeName")]
.
Fantastic!
I would be interested in someone experimenting with what serde_derive could do to integrate these sorts of extensions (skip_serializing_none is another one) more nicely. For example you could imagine that serde_derive could apply this transformation:
use serde_prefix::prefix_all;
// written by caller:
#[derive(Serialize)]
#[serde(apply = "prefix_all", prefix = "test_")]
struct Struct {
/* ... */
}
// expands to:
#[prefix_all(prefix = "test_")]
#[derive(Serialize)]
struct Struct {
/* ... */
}
Or somewhat more cleverly:
// no `use` needed
// written by caller:
#[derive(Serialize)]
#[serde(prefix::all = "test_")] // anything with colons is recognized as extension
struct Struct {
/* ... */
}
// expands to:
#[serde_prefix::all = "test_"] // prepend `serde_` on original extension
#[derive(Serialize)]
struct Struct {
/* ... */
}
@dtolnay Would the #[serde(prefix-macro-here)]
macro need to be defined in the serde crate first? Or is there a functionality like that already?
And to answer my own question, it looks like it would need to be defined here: https://github.com/serde-rs/serde/blob/master/serde_derive/src/internals/attr.rs when implementing the container struct in the from_ast method, if I am correct.
Another question, should prefix::all
be considered meta? If that's the case we would need to change the syn crate as well.
I'm not sure this issue is supposed to be closed, as the suffix part is not yet implemented anywhere (AFAIK).
Some JSON protocols represent variant types using a common prefix. For example a network result may be transmitted as
"NetworkResult_Success"
/"NetworkResult_Failure"
. In Rust we would like to represent such values as enum variantsNetworkResult::Success
andNetworkResult::Failure
. This is possible with Serde rename attributes but somewhat verbose.It would be nicer to have an attribute macro that inserts a given prefix as a rename attribute on each field, generating the code above.