bon icon indicating copy to clipboard operation
bon copied to clipboard

Introduce `derive(Projection)` to generate a type with the subset of the fields from the original

Open Veetaha opened this issue 1 year ago • 2 comments

I have such proc macro already implemented in a private repo at work. So this issue is basically a note for myself to move it to bon and expose as a public API here.

The API of this derive looks like this:

#[derive(Debug, Clone, Projection)]
#[projection(attrs = "derive(Debug, Clone)")]
struct Source {
    #[projection(name = "Proj1, Proj2")]
    field1: &'static str,

    #[projection(name = "Proj2")]
    field2: bool,

    #[projection(name = "Proj1, Proj3, Proj2")]
    field3: u64,
}

let source = Source {
    field1: "golden",
    field2: true,
    field3: 89,
};

assert_debug_eq(
    &source.to_proj1(),
    expect![[r#"
        Proj1 {
            field1: "golden",
            field3: 89,
        }"#]],
);

This generates three projection type Proj1, Proj2 and Proj3 with additional derive(Debug, Clone) attributes added to every projection.

I'd like to improve this API a bit. Re-visit the syntax and basically re-design it with the fresh mind (it's a really old macro at this point).

This should also somehow integrate with the bon::Builder derives. There should be some conversion method (e.g. From impl) to convert a projection into the partial builder or vice versa.

A note for the community from the maintainers

Please vote on this issue by adding a 👍 reaction to help the maintainers with prioritizing it. You may add a comment describing your real use case related to this issue for us to better understand the problem domain.

Veetaha avatar Sep 13 '24 12:09 Veetaha

My use-case for this would basically be to pass something with the data equivalent to a partial builder across a function boundary or some other place where I need to name the type.

It came up specifically in a situation where I wanted to convert a struct A with about 10 fields (too many to look nice as individual parameters in other words) to zero, one or more struct B where some fields are essentially copied over at the top level to all struct B created from the same struct A and one field is converted by a trait which is recursively applied to the remaining field and nested members. There it would have been nice if I could have just passed the partial builder into the conversion function to be cloned every time a trait implementation needs to actually create a value of struct B.

taladar avatar Sep 13 '24 12:09 taladar

I just found this interesting crate frunk that allows one to project structs already using the transmogrify operation

Veetaha avatar Nov 26 '24 17:11 Veetaha