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

Add struct-level annotation for renaming fields #140

Closed
erickt opened this issue Aug 21, 2015 · 9 comments
Closed

Add struct-level annotation for renaming fields #140

erickt opened this issue Aug 21, 2015 · 9 comments

Comments

@erickt
Copy link
Member

erickt commented Aug 21, 2015

Serde supports field level renaming with:

struct Foo {
  #[serde(rename="baz")]
  bar: usize
}

But this can be inconvenient to use if you have a lot of fields you need to rename, such as going from rust's "snake-case" style into "camel-case". It would be nice to have struct level renaming support for this:

#[serde(rename_camel_case)]
#[derive(Serialize, Deserialize)]
struct CamelCase {
  foo_bar_baz: usize
}

#[serde(rename_underscore_to_hypens)]
#[derive(Serialize, Deserialize)]
struct Hyphens {
  foo_bar_baz: usize
}

Would get serialized to fooBarBaz, and foo-bar-baz.

@erickt
Copy link
Member Author

erickt commented Feb 17, 2016

This was implemented a while ago.

@williamho
Copy link

does this feature still exist? I can't seem to find it in the docs.

@francesca64
Copy link

@williamho figuring out how to do this was surprisingly tricky, as the syntax apparently changed a few times, and it really doesn't seem to be documented anywhere. This is what worked for me:

#[derive(Debug, Deserialize)]
pub struct UploadResponse {
    fid: String,
    #[serde(rename="fileUrl")]
    file_url: String
}

@dtolnay
Copy link
Member

dtolnay commented Feb 20, 2017

@scottpleb your specific use case is documented here: https://serde.rs/attr-rename.html

All the attributes are documented here: https://serde.rs/attributes.html

@dtolnay
Copy link
Member

dtolnay commented Feb 21, 2017

I don't think this was ever implemented.

@dtolnay dtolnay reopened this Feb 21, 2017
@dtolnay
Copy link
Member

dtolnay commented Feb 23, 2017

@46bit mentioned possibly being interested in working on this.

Possibly the easiest implementation would be right above this line, traverse the "body" and apply all of the renames in place. So if we have the item attrs asking for camelCase, we would change all of the names of the fields (except those that already have a rename) to be camelCase.

Alternatively you could take a reference to this guy or just its bulk rename field, and pass it through these1 two2 calls so the field names get set correctly right away rather than having to update them later. Try whichever one seems easier to you.

In terms of the actual attributes, I don't like @erickt's serde(rename_camel_case) and serde(rename_underscore_to_hypens), would prefer to use a string so the names can look evocative like what the reader would see if these were individual rename attributes. Something like:

#[serde(rename_all = "snake_case")]
#[serde(rename_all = "kebab-case")]
#[serde(rename_all = "SNAKE_CASE")]
#[serde(rename_all = "camelCase")]
#[serde(rename_all = "PascalCase")]

Bonus points for not even looking at the word, just the casing.

#[serde(rename_all = "easterEggCase")]

@46bit
Copy link
Contributor

46bit commented Feb 23, 2017

Awesome. I like rename_all and agree exactly on the code demos you've put. But I'd like to allow users to use their own renaming function, similar to with #[serde(default = "fn")].

The obvious signature would be a mapping from field name to output name, fn(&str) -> &str. We could also provide the other field names in the container with fn(&str, [&str]) -> &str, but I don't see a usecase.

@46bit
Copy link
Contributor

46bit commented Feb 23, 2017

After doing some implementation, I don't know if renaming by function is possible without wider changes. default works because when the code being analysed is run that function will be available. That's not the case when renaming inside the codegen.

There exists the Inflector crate to perform inflection. That adds a dependency and relies on std::ascii. Would that be acceptable? Otherwise I can reimplement.

@dtolnay
Copy link
Member

dtolnay commented Feb 25, 2017

Implemented in #788.

@dtolnay dtolnay closed this as completed Feb 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants