How to use match to check two different Enum types

Below is my code. The message is passed by another application. This application may send PeerCommand or PeerEvent. But once I check message is a PeerCommand type then I cannot check if the message is PeerEvent. Im getting mismatched types compile-time error.

Ok(match serde_json::from_str(&line) {
        Err(err) => Err(err)?,
        Ok(message) => match message {
            PeerCommand::Leave { id, client_id } => {
                info!("Received Peer leave command id::{} client::{}",id, client_id);
                broker
                    .send(Message::LeavePeer { id, peer_id: client_id })
                    .await
                    .unwrap();
            },
            PeerCommand::Connect { id, client_id, port: _ } => {
                warn!("Peer {} Connect command, id {} ",client_id,id);
            },
            PeerCommand::Test { id, peer_id, message } => {
                info!("Peer {} test command with message {}, id :: {}",peer_id,message,id);
            },
        },

        Ok(message) => match message {
            PeerEvent::Connected { id, client_id, port } => {} // mismatched types error
        },
    })

serde_json::from_str(&line) is a generic function that returns a value with the type serde_json::Result<T>, where T is the type you're deserializing the line into.

The first match message means that message must be a PeerCommand, therefore serde_json::Result<T> must be a serde_json::Result<PeerCommand>, and the compiler will generate code that deserializes a PeerCommand from the JSON. But inside the second match message, message must be a PeerEvent. Hence an error: serde_json::from_str(&line) can't return both a serde_json::Result<PeerCommand> and serde_json::Result<PeerEvent> at the same time.

If you want to deserialize something that is either a PeerCommand or PeerEvent, you need to make an enum that models that:

#[derive(Deserialize)]
enum PeerCommandOrPeerEvent {
    PeerCommand(PeerCommand),
    PeerEvent(PeerEvent),
}

You may need to add a serde attribute like #[serde(tag = "something")] to the enum to make it work depending on what the JSON you're working with actually looks like. You can read about such attributes here: Enum representations · Serde

By the way, it's always best if you add the full compiler error that cargo check outputs, it makes it a lot easier for someone reading your post to see what the issue is.

1 Like

Thanks, @Heliozoa, will try what you have suggested.
Also, will add the cargo check next time.

1 Like

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.