dtolnay / request-for-implementation

Crates that don't exist, but should
610 stars 6 forks source link

Macro to serialize and deserialize trait object using internal type tag #14

Closed dtolnay closed 5 years ago

dtolnay commented 5 years ago

There is currently no simple way to make a boxed trait object deserializable via an internal tag that determines its concrete type. I would like to be able to express trait objects as:

#[serde_trait_object]
trait MyTrait {
    /* whatever trait methods */
}

struct A {
    a: u8,
}

#[serde_trait_object]
impl MyTrait for A {}

// possibly in a different crate
struct B {
    b: u8,
}

#[serde_trait_object]
impl MyTrait for B {}

The attribute macro would insert whatever supertraits and trait methods are necessary to make this work, probably using erased-serde for the object safety and inventory for a registry of all trait implementations compiled into the program.

The serialized form of these types should carry a type tag, similar to what you might see with polymorphic deserialization using Jackson in Java.

{
    "type": "A",
    "a": 0
}

{
    "type": "B",
    "b": 0
}

If more than one deserializable type in the program has the same name, the deserialization should error at runtime and recommend renaming one of the types or using a #[serde(rename = "...")] attribute to make its tag unique.

dtolnay commented 5 years ago

I am going to get started on this one myself.

dtolnay commented 5 years ago

Implemented in https://github.com/dtolnay/typetag!