Idiomatic way to match and route websocket message types?

Hi,

I connect to a server using tungstenite async and am only able to identify and route the incoming messages if deserialization succeeds for a given String.
The first if block has to identify if eventType field is present, after that there might be different event types to be matched, is an Enum useful here?

The other two if blocks are for messages that have a different structure.

pub fn deserialize(message:String){
        
        if let Ok(message) = serde_json::from_str::<EventType>(&message) {
              ...enums?
        }

        if let Ok(message) = serde_json::from_str::<ResultMessage>(&message) {
        }

        if let Ok(message) = serde_json::from_str::<ErrorMessage>(&message) {
        }
    }

Also, should the EventType block be moved to a different function?

Make an enum of all of your message types with #[serde(untagged)] and serde will do this search for you.

1 Like

thanks! That does the job well. But now I end up with some duplicate syntax within my enum

    #[derive(Deserialize, Debug)]
    pub struct MyMessageType{

        #[serde(rename="e")] event_type: String,
        #[serde(rename="u")] update_id: u64,
    }

    #[derive(Deserialize, Debug)]
    #[serde(untagged)]
    pub enum MessageType {

        MyMessageType(MyMessageType),
    }

but I would like to directly put the strut inside my enum:


    pub enum MessageType {

        MyMessageType,
    }

Rust enums don't work that way — every variant with fields must have both a variant name and specify the types of the fields. However, the name of the variant doesn't matter for deserialization (because of the serde(untagged) option), so you can make it short.


#[derive(Deserialize, Debug)]
#[serde(tag = "e")]
enum EventMessage {...}

#[derive(Deserialize, Debug)]
struct ResultMessage {...}

#[derive(Deserialize, Debug)]
struct ErrorMessage {...}

#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum Message {
    Event(EventMessage),
    Result(ResultMessage),
    Error(ErrorMessage),
}
3 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.