Skip to content

Feature request: struct field names as enum variants rather than strings #31

@mmirate

Description

@mmirate

I'd like to ensure statically that the user of my library will not be sending completely wrong/typo'd data through my library to the network peer when he chooses which struct fields to interact-with. This means that instead of getting strings he should get "unit"-type enum variants (with serde implementation so that when I get them I can serialize them to the network peer as-is). All the building blocks are already present:

mod one_particular_endpoint {
    #[derive(
        Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
        strum::VariantArray, serde::Deserialize, serde::Serialize
    )]
    #[serde(rename_all="camelCase")] // network peer wants camel case 🤢
    #[strum(serialize_all="camelCase")]
    pub enum ResponseField { Id, Name, /* more ... */ }

    #[derive(Debug, Clone, serde::Deserialize, partially::Partial, FieldNamesAsSlice)]
    #[partially(derive(Debug, Clone, serde::Deserialize, FieldNamesAsSlice))]
    #[field_names_as_slice(rename_all="camelCase")]
    #[serde(rename_all="camelCase")]
    pub struct ResponseItem<'a> { pub id: u64, pub name: Cow<'a, str>, /* more ... */ }

    // then a trait impl, which has ResponseField and ResponseItem<'a> as associated type parameters, and which does all the real work
}
// then a couple hundred more similar submodules

... but there's no way to check at compile-type for every possible impl of that trait (i.e. with one check in the declaration of the trait rather than with a separate check for every use of this pattern) that ResponseField's variants and ResponseItem's fields are equal, not even with static_assertions; so this kind of mistake could lurk anywhere making the whole thing unworkable.

However, that check wouldn't be needed if this crate could generate that entire ResponseField enum type declaration from the struct type declaration's fields. The array of all the enum's variants would not even be needed because the strum crate already does that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions