use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize)] pub struct Message { src: String, #[serde(rename = "dest")] dst: String, body: MessageBody, } #[derive(Debug, Deserialize, Serialize)] pub struct MessageBody { #[serde(rename = "msg_id")] id: Option, in_reply_to: Option, #[serde(flatten)] data: MessagePayload, } #[derive(Debug, Deserialize, Serialize, PartialEq)] #[serde(tag = "type")] #[serde(rename_all = "snake_case")] pub enum MessagePayload { Init { node_id: String, #[serde(rename = "node_ids")] nodes: Vec, }, } #[cfg(test)] mod tests { use super::*; #[test] fn protocol_decode_init() -> color_eyre::Result<()> { let json_input = r###"{ "src": "c1", "dest": "n3", "body": { "type": "init", "msg_id": 1, "node_id": "n3", "node_ids": ["n1", "n2", "n3"] } } "###; let msg = serde_json::from_str::(json_input)?; assert!(matches!(msg.body.data, MessagePayload::Init { .. })); Ok(()) } }