Skip to content

FromForm flatten attribute #1916

Open
Open
@ijackson

Description

@ijackson

When using derive, it is often useful to be able to make common structs that contain fields where everything can be done automatically, and then surrounding structs where only some of the things are derived.

To do this, one needs to indicate to each derive macro that the fields of a contained struct should be imported without another level of nesting. #[serde(flatten)], #[row(flatten)]. But unfortunately there is not a #[field(flatten)].

For example, I have this in a work-in-progress webapp:

#[derive(Debug,Serialize)]
struct PageContext {
    #[serde(flatten)] frow: FlightRow,
    hidden_vals: TemplateEnumRadio<IsHidden>,
}

#[derive(Debug,Serialize,FromSqlRow)]
struct FlightRow {
    flight: Flight,
    branch: String,

    hidden: IsHidden,

    webgroup: String,
    main_tree: String,
    template_flight: Option<Flight>,
    basis_flight: Option<Flight>,
    reuse_real_builds: bool,

    xtrees_web: String,
    xtrees_main: String,
    job_patterns: String,

    #[serde(flatten)] #[row(flatten)]
    common: RowUpdateCommon,
}

#[derive(Debug,FromForm)]
struct UpdateForm {
    common: RowUpdateCommon, // this wants to be flatten
}

#[derive(Debug,Serialize,FromForm,FromSqlRow)]
struct RowUpdateCommon {
    email: String,
}

This doesn't work because the generated code expects form submissions containing common.email but the actual form contains only email.

Alternatives Considered

Letting the fields be nested the way FromForm wants doesn't really work, because whether a field ends up in common depends not on anything principled about the system, but simply on whether the automatic handling produced by the derive macros is appropriate.

For now I have to just give up on making this part of my code common, and writing some boilerplate to copy fields from one struct to another.

Additional Context

I'm not convinced that field is a good name for this attribute. Derive macro inert attributes are in a global namespace. I suggest that form would be better. However, it is perhaps too late to change this now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedAn accepted request or suggestionrequestRequest for new functionality

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions