Seperate message parsing logic

This commit is contained in:
Dane Johnson 2022-10-03 14:18:25 -05:00
parent 9826a00141
commit fbaf386ebb
2 changed files with 75 additions and 40 deletions

View File

@ -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,
}
}

51
src/message.rs Normal file
View File

@ -0,0 +1,51 @@
#[derive(PartialEq, Debug)]
pub struct Message<'a> {
pub command: &'a str,
pub args: Vec<&'a str>,
}
pub type Result<T> = std::result::Result<T, Error>;
#[repr(u8)]
#[derive(PartialEq, Debug)]
pub enum Error {
BadParse,
UnknownCommand,
}
impl<'a> Message<'a> {
pub fn parse(text: &'a str) -> Result<Message<'a>> {
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(())
}
}