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

Request: Implement a rename_all = ... attribute for types #73

Open
phrohdoh opened this issue Aug 23, 2019 · 2 comments
Open

Request: Implement a rename_all = ... attribute for types #73

phrohdoh opened this issue Aug 23, 2019 · 2 comments
Labels
help wanted Extra attention is needed

Comments

@phrohdoh
Copy link
Contributor

phrohdoh commented Aug 23, 2019

💡 Feature description

Similar to serde's rename_all attribute, this would reformat all of the type's fields / variants for de/serialization to the format specified.

Individual field / variant rename must take precedence over rename_all.

Valid format values should be, at minimum:

  • snake_case
  • kebab-case
  • camelCase
  • PascalCase
  • SCREAMING_SNAKE_CASE
  • SCREAMING-KEBAB-CASE
  • UPPERCASE
  • lowercase

This rename_all attribute should probably be applicable to types and enum variants.

💻 Basic example

#[derive(Item, PartialEq, Debug, Clone)]
#[dynomite(rename_all = "kebab-case")]
struct Recipe {
    #[dynomite(partition_key]
    #[dynomite(rename = "recipe_id")]
    id: String,
    net_carbs: u64,
}

Should be serialized (to JSON just as an example) as:

{
    "recipe_id": "...",
    "net-carbs": 0
}

references / prior work

@softprops softprops added the help wanted Extra attention is needed label May 16, 2020
@phrohdoh
Copy link
Contributor Author

We should consider adding heck, an opinionated & non-customizable case-conversion 3rd-party library crate, as a dependency to the dynomite-derive crate to reduce rework and (potentially) simplify implementation (and testing!) of this feature (since it reformats the existing name, instead of providing a new name entirely).

@phrohdoh
Copy link
Contributor Author

phrohdoh commented Jan 22, 2021

I've written code that makes the following test pass (using the heck crate, just an implementation detail though).
If there is any interest (not seeing any so far on the ticket; no thumbs-up etc),
I could continue working on the implementation I currently have.
Of course I prefer to not unnecessarily bloat dynomite.

rename_all type-level dynomite attr
#[test]
#[allow(non_snake_case /* specifically testing mixed-case fields */)]
fn derive_item_rename_all_attr_kebab_case() {
    // GIVEN
    #[derive(Item)]
    #[dynomite(rename_all = "kebab-case")]
    struct MyItem {
        #[dynomite(partition_key)]
        _pk: String,
        #[dynomite(sort_key)]
        sk: String,
        #[dynomite(rename = "fooBar")]
        with_Field_levelRename: Option<i32>,

        snake_case: bool,
        camelCase: bool,
        PascalCase: bool,
        SCREAMING_SNAKE_CASE: bool,
        UPPERCASE: bool,
        lowercase: bool,
    }

    let original = MyItem {
        _pk: "6956abd4-665f-433a-b9ad-c038f9c64601".into(),
        sk: "2021-01-20T22:41:41.603Z".into(),
        with_Field_levelRename: Some(1024),
        snake_case: true,
        camelCase: true,
        PascalCase: true,
        SCREAMING_SNAKE_CASE: true,
        UPPERCASE: true,
        lowercase: true,
    };

    // WHEN
    let attrs: Attributes = original.into();

    // THEN
    assert_eq!(attrs.len(), 9);
    assert!(attrs.contains_key("_pk"), "leading underscore retained");
    assert!(attrs.contains_key("sk"), "unchanged");
    assert!(attrs.contains_key("fooBar"), "field-level rename has precedent");
    assert!(attrs.contains_key("snake-case"));
    assert!(attrs.contains_key("camel-case"));
    assert!(attrs.contains_key("pascal-case"));
    assert!(attrs.contains_key("screaming-snake-case"));
    assert!(attrs.contains_key("uppercase"));
    assert!(attrs.contains_key("lowercase"));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants