Serde: Tagged enum, binary representation deserialization

I'm trying to implement a deserializer for a specific protocol however I'm struggling to understand how exactly to go about deserializing the enum based on the tag that exists in the message data.

The protocol format is:

length (uint32)
command code (char)
command specific data (depends on the data object)

An example of some of the commands that can exist are:

pub enum MtaEvent {
    Connect {
        hostname: String,
        protocol_family: char,
        address: String,
        port: u16,
    },
    Helo {
        hostname: String
    },
    EnvelopeFrom {
        sender: String,
        arguments: Vec<String>,
    },
}

My deserializer can successfully deserialize the command specific data if it sent - however I'm unsure how I can handle the command code section of the data, from reading the enum representations documentation I feel that I need the internally tagged representation but I'm not sure how I would actually handle this, given the tag is a single char.

I was thinking, I could potentially wrap my MtaEvent object within a struct that looks like:

struct event {
    length: u32,
    command: char,
    event_data: MtaEvent,
}

With some form of validation method that ensures the event_data does actually match the given command char, however I was hoping there was some way to avoid this, instead attempting to do something like:

pub enum MtaEvent {
    #[serde(tag = "", content = "C")]
    Connect {
        hostname: String,
        protocol_family: char,
        address: String,
        port: u16,
    },
   #[serde(tag = "", content = "H")]
    Helo {
        hostname: String
    },
    #[serde(tag = "", content = "M")]
    EnvelopeFrom {
        sender: String,
        arguments: Vec<String>,
    },
}

Which would then allow all the identification of which type of event I'm deserializing to be completed for me.

Is this possible, or am I thinking about this the wrong way?

I would probably not use serde for this. I tried to implement a deserializer for a file format a while back and after playing around with it for a while, I eventually abandoned it. I gave up on it because I came to realize I wasn't getting much value out of serde when the Deserializer only made sense for a particular destination data structure. I ended up just switching to implementing a parser that returned the type of interest.

serde seems to be most valuable for formats that can store arbitrary data like json, bincode, xml, etc. That said, this was just the conclusion I came to, and not necessarily the conclusion of someone who understands serde better would come to. In your case I would think implementing a parser that returns an iterator of events would be more straight forward and a better fit for what your doing.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.