use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ClientMessage {
Join { room: String, username: String },
Send { room: String, text: String },
Private { to: String, text: String },
Ping,
}
#[derive(Debug, Clone, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ServerMessage {
Joined { room: String, username: String },
Message { room: String, from: String, text: String, at: u64 },
Private { from: String, text: String },
UserJoined { room: String, username: String },
UserLeft { room: String, username: String },
Error { code: String, message: String },
Ping,
Pong,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deserialize_join() {
let json = r#"{"type":"join","room":"general","username":"alice"}"#;
let msg: ClientMessage = serde_json::from_str(json).unwrap();
match msg {
ClientMessage::Join { room, username } => {
assert_eq!(room, "general");
assert_eq!(username, "alice");
}
_ => panic!("expected Join"),
}
}
#[test]
fn test_deserialize_send() {
let json = r#"{"type":"send","room":"general","text":"hola!"}"#;
let msg: ClientMessage = serde_json::from_str(json).unwrap();
match msg {
ClientMessage::Send { room, text } => {
assert_eq!(room, "general");
assert_eq!(text, "hola!");
}
_ => panic!("expected Send"),
}
}
#[test]
fn test_deserialize_private() {
let json = r#"{"type":"private","to":"bob","text":"hey"}"#;
let msg: ClientMessage = serde_json::from_str(json).unwrap();
match msg {
ClientMessage::Private { to, text } => {
assert_eq!(to, "bob");
assert_eq!(text, "hey");
}
_ => panic!("expected Private"),
}
}
#[test]
fn test_deserialize_ping() {
let json = r#"{"type":"ping"}"#;
let msg: ClientMessage = serde_json::from_str(json).unwrap();
match msg {
ClientMessage::Ping => {}
_ => panic!("expected Ping"),
}
}
#[test]
fn test_serialize_joined() {
let msg = ServerMessage::Joined {
room: "general".into(),
username: "alice".into(),
};
let json = serde_json::to_string(&msg).unwrap();
assert_eq!(json, r#"{"type":"joined","room":"general","username":"alice"}"#);
}
#[test]
fn test_serialize_message() {
let msg = ServerMessage::Message {
room: "general".into(),
from: "alice".into(),
text: "hola!".into(),
at: 1720123456,
};
let json = serde_json::to_string(&msg).unwrap();
assert_eq!(
json,
r#"{"type":"message","room":"general","from":"alice","text":"hola!","at":1720123456}"#
);
}
#[test]
fn test_serialize_private() {
let msg = ServerMessage::Private {
from: "bob".into(),
text: "hey".into(),
};
let json = serde_json::to_string(&msg).unwrap();
assert_eq!(json, r#"{"type":"private","from":"bob","text":"hey"}"#);
}
#[test]
fn test_serialize_user_joined() {
let msg = ServerMessage::UserJoined {
room: "general".into(),
username: "carol".into(),
};
let json = serde_json::to_string(&msg).unwrap();
assert_eq!(
json,
r#"{"type":"user_joined","room":"general","username":"carol"}"#
);
}
#[test]
fn test_serialize_user_left() {
let msg = ServerMessage::UserLeft {
room: "general".into(),
username: "carol".into(),
};
let json = serde_json::to_string(&msg).unwrap();
assert_eq!(
json,
r#"{"type":"user_left","room":"general","username":"carol"}"#
);
}
#[test]
fn test_serialize_error() {
let msg = ServerMessage::Error {
code: "room_not_found".into(),
message: "la sala no existe".into(),
};
let json = serde_json::to_string(&msg).unwrap();
assert_eq!(
json,
r#"{"type":"error","code":"room_not_found","message":"la sala no existe"}"#
);
}
#[test]
fn test_serialize_ping() {
let msg = ServerMessage::Ping;
let json = serde_json::to_string(&msg).unwrap();
assert_eq!(json, r#"{"type":"ping"}"#);
}
#[test]
fn test_serialize_pong() {
let msg = ServerMessage::Pong;
let json = serde_json::to_string(&msg).unwrap();
assert_eq!(json, r#"{"type":"pong"}"#);
}
}