lloydmeta / frunk

Funktional generic type-level programming in Rust: HList, Coproduct, Generic, LabelledGeneric, Validated, Monoid and friends.
https://beachape.com/frunk/
MIT License
1.24k stars 56 forks source link

Converting struct with enum members #193

Open janosimas opened 3 years ago

janosimas commented 3 years ago

Hi, I just started using this crate and looks quite promising!

I want to check if there is some limitation with the crate or maybe I'm doing something wrong. Here is what I found in my tests:

Is the correct? Is it possible to convert a complex struct with enum fields?

Here is a minimal example. I have a BaseStruct with an BaseEnum field, all of them derive from LabelledGeneric, and I want to convert to a TargetStruct with a TargetEnum field. All of the them have the same names and member order.

extern crate frunk;
extern crate frunk_core;

use frunk::{labelled::Transmogrifier, LabelledGeneric};

fn main() {
    // works
    let target: TargetEnum = frunk::labelled_convert_from(BaseEnum::default());

    // works
    let target: TargetStruct = frunk::labelled_convert_from(BaseStruct::default());
    let target: TargetStruct = frunk::transform_from(BaseStruct::default());
    let target: TargetStruct = BaseStruct::default().transmogrify();
    // Doesn't work
    let target: TargetStruct = frunk::from_labelled_generic(BaseStruct::default());

    // No conversion works for the "complex" struct
    let target: TargetComplexStruct = frunk::labelled_convert_from(BaseComplexStruct::default());
    let target: TargetComplexStruct = frunk::from_labelled_generic(BaseComplexStruct::default());
    let target: TargetComplexStruct = frunk::transform_from(BaseComplexStruct::default());
    let target: TargetComplexStruct = BaseComplexStruct::default().transmogrify();
}

#[derive(Clone, PartialEq, Eq, Hash, Debug, LabelledGeneric)]
enum BaseEnum {
    SomeValue,
}

impl Default for BaseEnum {
    fn default() -> Self {
        BaseEnum::SomeValue
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Debug, LabelledGeneric)]
enum TargetEnum {
    SomeValue,
}

#[derive(Default, Clone, PartialEq, Eq, Hash, Debug, LabelledGeneric)]
struct BaseStruct {
    test: String,
}

#[derive(Clone, PartialEq, Eq, Hash, Debug, LabelledGeneric)]
struct TargetStruct {
    test: String,
}

#[derive(Default, Clone, PartialEq, Eq, Hash, Debug, LabelledGeneric)]
struct BaseComplexStruct {
    test: String,
    other: BaseEnum,
}

#[derive(Clone, PartialEq, Eq, Hash, Debug, LabelledGeneric)]
struct TargetComplexStruct {
    test: String,
    other: TargetEnum,
}
azzamsa commented 1 year ago

Yes. Looking for the same thing. I tried many approaches but had no luck.