[Solved] Question about typetag

The typetag crate has simplified my code in the way it deserializes traits. However, I got stuck on an error the first time I tried to us it.

I have a Message trait. Each struct implementing that trait has a MsgHdr struct and a struct that implements a MsgPayload trait.

#[typetag::serde(tag = type)]
trait Msg {}
#[typetag::serde(tag = type)]
trait MsgPayload {}
struct MsgHdr {}
struct MsgType1 {
    header: MsgHdr,
    payload: MsgPayloadType1
}
#[typetag::serde]
impl Msg for MsgType1 {}
struct MsgPayloadType1 {}
#[typetag::serde]
impl MsgPayload for MsgPayloadType1 {}

When I deserialize with

let foo = msg: Box<dyn Msg> = serde_json::from_str(serialized)?;

I get

missing field type at line 1 column 204

let foo: SpecificType = serde_json::from_str(string);

works, so I don’t think the problem is in my code.

I have no idea what I did wrong.

The json data would need to have an entry called “type” to identify which implementation of the trait object to deserialize into. For example if MsgType1 deserializes from:

{"header":{},"payload":{}}

then Box<dyn Msg> could deserialize into the same thing from:

{"type":"MsgType1","header":{},"payload":{}}

Thanks for the quick response. That fixed it.

I was assuming that typetag would insert the “type” field for me. Could it? Should it? It would be nice if it did and then removed it on deserialization. I had to edit a gazillion (well, only half a gazillion) struct definitions to add the “type” field. It took three tries because of typos.

If you serialize a dyn Msg trait object, typetag will insert the right type field.