From fbaf386ebb65b5fe55e0cdc096e264cd47054b53 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Mon, 3 Oct 2022 14:18:25 -0500 Subject: [PATCH] Seperate message parsing logic --- src/main.rs | 64 +++++++++++++++++++------------------------------- src/message.rs | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 40 deletions(-) create mode 100644 src/message.rs diff --git a/src/main.rs b/src/main.rs index 4815ded..6245837 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,9 +3,12 @@ use std::thread; use std::sync::{Arc, Mutex}; use std::collections::HashMap; +mod message; +use message::Message; + use rand::RngCore; -use tungstenite::protocol::Message; +use tungstenite::protocol::Message as WsMessage; use sha2::{Sha256, Digest}; @@ -21,34 +24,32 @@ fn main() { thread::spawn (move || { let mut ws = tungstenite::accept(stream.unwrap()).unwrap(); println!("New client!"); - ws.write_message(Message::Text("HOSTJOIN:".to_string())).unwrap(); + ws.write_message(WsMessage::Text("HOSTJOIN:".to_string())).unwrap(); loop { let message = ws.read_message(); println!("{:?}", message); match message { Err(_) => break, - Ok(Message::Close(_)) => break, - Ok(Message::Text(msg)) => - match parse(msg.as_str().trim()) { - Some(("HOST:", _)) => { - let code = code_generator.lock().unwrap().generate(); - let mut room = Room::default(); - let player = Player { name: "Guest".to_string() }; - room.players.push(player); - rooms.lock().unwrap().insert(code.clone(), room); - ws.write_message(Message::Text(code)).unwrap(); - }, - Some(("JOIN:", args)) => { - let code = args[0]; - let room = rooms.lock().unwrap().get(&code.to_string()); - match room { - Some(mut room) => { - room. - } - _ => unimplemented!(), - }, + Ok(WsMessage::Close(_)) => break, + Ok(WsMessage::Text(msg)) => { + let msg = Message::parse(msg.as_str().trim()); + match msg { + Ok(msg) => + match msg.command { + "HOST" => { + let code = code_generator.lock().unwrap().generate(); + let mut room = Room::default(); + let player = Player { name: "Guest".to_string() }; + room.players.push(player); + rooms.lock().unwrap().insert(code.clone(), room); + ws.write_message(WsMessage::Text(code)).unwrap(); + } + _ => todo!(), + } + Err(_) => todo!(), + } + } _ => unimplemented!(), - } } }); @@ -92,20 +93,3 @@ impl Default for CodeGenerator { } } } - -fn parse(s: &str) -> Option<(&str, Vec<&str>)> { - let re = regex::Regex::new(r"(^[A-Z_]):\w*(.*)").unwrap(); - match re.captures(s) { - Some(captures) => { - if captures.len() < 3 { - None - } else { - Some(( - captures.get(1).unwrap().as_str(), - captures.get(2).unwrap().as_str().split(',').collect(), - )) - } - } - None => None, - } -} diff --git a/src/message.rs b/src/message.rs new file mode 100644 index 0000000..7a0494c --- /dev/null +++ b/src/message.rs @@ -0,0 +1,51 @@ +#[derive(PartialEq, Debug)] +pub struct Message<'a> { + pub command: &'a str, + pub args: Vec<&'a str>, +} + +pub type Result = std::result::Result; + +#[repr(u8)] +#[derive(PartialEq, Debug)] +pub enum Error { + BadParse, + UnknownCommand, +} + +impl<'a> Message<'a> { + pub fn parse(text: &'a str) -> Result> { + let re = regex::Regex::new(r"^([A-Z_]+):\s*(.*)").unwrap(); + match re.captures(text) { + Some(captures) => { + if captures.len() < 3 { + Err(Error::BadParse) + } else { + let command = captures.get(1).unwrap().as_str(); + let args = captures.get(2).unwrap().as_str() + .split(',') + .map(|s| s.trim()) + .collect(); + Ok(Message { command, args }) + } + } + None => Err(Error::BadParse), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_parse() -> Result<()> { + let text = "COMMAND: arg1, arg2"; + let msg = Message::parse(text)?; + assert_eq!(Message { + command: "COMMAND", + args: vec!["arg1", "arg2"], + }, msg); + + Ok(()) + } +}