Serializing and Deserializing between modules in complicated situation

I'm sorry, but I don't understand your problem. I feel like the solution @H2CO3 gave you here:

should work in this case, too. Maybe your real-world code has some extra difficulties not covered in your example? Even with typetag, using the #[serde(untagged)] attribute on crate_new::MyStruct allows you to deserialize crate1_box_str as Box<dyn crate_new::MyTrait>:

/*
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
typetag = "*"
*/

pub mod crate_old {
    use serde::{Deserialize, Serialize};

    #[derive(Debug, Clone, Serialize, Deserialize)]
    pub struct MyStruct(
        #[serde()]
        pub usize
    );

    #[typetag::serde(tag = "MyTrait", content = "value")]
    pub trait MyTrait {}

    #[typetag::serde]
    impl MyTrait for MyStruct {}
}

pub mod crate_new {
    use serde::{Deserialize, Serialize};

    #[derive(Debug, Clone, Serialize, Deserialize)]
    #[serde(untagged)]
    pub enum MyStruct {
        RealStruct(usize),
    }

    #[typetag::serde(tag = "MyTrait", content = "value")]
    pub trait MyTrait {}

    #[typetag::serde]
    impl MyTrait for MyStruct {}
}

fn main() {
    let crate1_box: Box<dyn crate_old::MyTrait> = Box::new(crate_old::MyStruct(10));
    let crate1_box_str = serde_json::to_string(&crate1_box).unwrap();
    assert_eq!(crate1_box_str, r#"{"MyTrait":"MyStruct","value":10}"#);

    let crate2_box: Box<dyn crate_new::MyTrait> = Box::new(crate_new::MyStruct::RealStruct(10));
    let crate2_box_str = serde_json::to_string(&crate2_box).unwrap();
    assert_eq!(crate2_box_str, crate1_box_str);

    let crate2_box: Box<dyn crate_new::MyTrait> = serde_json::from_str(&crate1_box_str).unwrap();
}

Rustexplorer.

2 Likes