typetag: apparent cross-crate incompatibility wrecks enums
( 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.
Issue has had no activity in the last 180 days and is going to be closed in 7 days if no further activity occurs
@workingjubilee Could you perhaps send me a failing example (I haven't used typetag before). Thanks!
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
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)