openws-server 0.1.2

WebSocket server with room-based messaging, private messages, HTTP broadcast, and configurable limits
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"}"#);
    }
}