ron icon indicating copy to clipboard operation
ron copied to clipboard

typetag: apparent cross-crate incompatibility wrecks enums

Open workingjubilee opened this issue 5 years ago • 2 comments

( side note: I '""love""" the new Github UI. )

When combined with typetag, the result does not appear to successfully parse RON enums -> serde enums -> trait objects, as I would expect. I am currently still trying to narrow the exact problem down, so I am not definitively sure whether it is an issue in this crate or the other one. Apologies. Currently in-progress.

workingjubilee avatar Jul 07 '20 06:07 workingjubilee

Issue has had no activity in the last 180 days and is going to be closed in 7 days if no further activity occurs

github-actions[bot] avatar Nov 18 '21 15:11 github-actions[bot]

@workingjubilee Could you perhaps send me a failing example (I haven't used typetag before). Thanks!

juntyr avatar Aug 26 '22 08:08 juntyr

Side note (since it's hard to find any working example): I tried RON with typetags and it was working correctly:

#[derive(Deserialize, Serialize, Debug)]
pub struct Component1 {
    value: f32,
    value_2: f32
}

#[derive(Deserialize, Serialize, Debug)]
pub struct Component2 {
    value: f32,
}

#[typetag::serde(tag = "type")]
trait MyTrait: Debug {
    fn do_stuff(&self){}
}

#[typetag::serde]
impl MyTrait for Component1 {
    fn do_stuff(&self){
        println!("{:#?}", self.value_2);
    }
}

#[typetag::serde]
impl MyTrait for Component2 {
    fn do_stuff(&self){
        println!("{:#?}", self.value);
    }
}


#[derive(Deserialize, Serialize, Debug)]
pub struct EntityConfig {
    pub name: String,
    pub components: Vec<Box<dyn MyTrait>>
}

fn main() {
    let file = fs::File::open("./data.ron").unwrap();
    let mut entity_config: EntityConfig = ron::de::from_reader(file).unwrap();
    assert_eq!(entity_config.components.len(), 2);
    for component in entity_config.components {
        component.do_stuff();
    }
}


data.ron:

EntityConfig(
    name: "some name",
    components: [
        {
            "type": "Component1",
            "value": 22,
            "value_2": 35.0
        },
        {
            "type": "Component2",
            "value": 3.14,
        },
    ]
)

output:

35.0
3.1

I also checked how it works if declared trait objects contain any enums – and in this very case everything works correctly as well:


#[derive(Deserialize, Serialize, Debug)]
enum SampleTestEnum {
    Test(i32),
    AnotherTest(f32, f32)
}

#[derive(Deserialize, Serialize, Debug)]
pub struct Component1 {
    value: f32,
    value_2: f32,
    something: SampleTestEnum
}

#[derive(Deserialize, Serialize, Debug)]
pub struct Component2 {
    value: f32,
}

#[typetag::serde(tag = "type")]
trait MyTrait: Debug {
    fn do_stuff(&self){}
}

#[typetag::serde]
impl MyTrait for Component1 {
    fn do_stuff(&self){
        match self.something {
            SampleTestEnum::Test(number) => {
                println!("my number: {:#?}", number);
            }
            SampleTestEnum::AnotherTest(float_1, float_2) => {
                println!("f1: {:#?}, f2: {:#?}", float_1, float_2);
            }
        }
    }
}

#[typetag::serde]
impl MyTrait for Component2 {
    fn do_stuff(&self){
        println!("{:#?}", self.value);
    }
}


#[derive(Deserialize, Serialize, Debug)]
pub struct EntityConfig {
    pub name: String,
    pub components: Vec<Box<dyn MyTrait>>
}

fn main() {
    let file = fs::File::open("./data.ron").unwrap();
    let mut entity_config: EntityConfig = ron::de::from_reader(file).unwrap();
    assert_eq!(entity_config.components.len(), 3);
    for component in entity_config.components {
        component.do_stuff();
    }
}

data.ron:

EntityConfig(
    name: "some name",
    components: [
        {
            "type": "Component1",
            "value": 22,
            "value_2": 35.0,
            "something": Test(22)
        },
        {
            "type": "Component1",
            "value": 12,
            "value_2": 11.0,
            "something": AnotherTest(11.0, 22.0)
        },
        {
            "type": "Component2",
            "value": 3.1,
        },
    ]
)

Output:

my number: 22
f1: 11.0, f2: 22.0
3.1

Yarwin avatar Oct 29 '22 18:10 Yarwin

I'll close this once I've added a test to ensure this remains working (and I hope I'll remember it with the new label)

juntyr avatar Apr 23 '23 17:04 juntyr