From c41bf83eb8689bf4d682d9a63fd0a2a69bfdbe30 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Wed, 12 Oct 2022 14:31:23 -0500 Subject: [PATCH] Allow for escaped commas in message --- src/client.rs | 7 +++++-- src/message.rs | 40 +++++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/client.rs b/src/client.rs index 18b476e..f18ef3f 100644 --- a/src/client.rs +++ b/src/client.rs @@ -42,6 +42,8 @@ impl Client { } } async fn handle_client_msg(&mut self, msg: Message) { + // HOST and JOIN are handled by the client to set up a connection + // TODO add id support for reconnecting users match msg.command.as_str() { "HOST" => { let room_code = self.global_state.code_generator.lock().await.generate(); @@ -86,8 +88,9 @@ impl Client { } } } - async fn handle_server_msg(&mut self, _msg: Message) { - todo!(); + async fn handle_server_msg(&mut self, msg: Message) { + // Forward the message via websocket + self.ws.send(msg).await.unwrap(); } } diff --git a/src/message.rs b/src/message.rs index b75b1c9..a242fc6 100644 --- a/src/message.rs +++ b/src/message.rs @@ -22,23 +22,40 @@ pub enum Error { } impl Message { + // pub fn parse(text: String) -> Result { + // let (command, mut tail) = text.split_once(":").ok_or(Error::BadParse)?; + // let command = String::new(command.trim()); + // let args = vec![]; + // loop { + // let tail = tail.trim_start(); + // if tail == "" { + // break + // } + // else { + // let mut escaped = true; + // tail.find + // } + // }; + // } pub fn parse(text: String) -> Result { + use regex::Regex; lazy_static! { - static ref RE: regex::Regex = regex::Regex::new(r"^([A-Z_]+):\s*(.*)").unwrap(); + static ref RE: Regex = Regex::new(r"^([A-Z_]+):\s*(.*)").unwrap(); + static ref ARGS_RE: Regex = Regex::new(r"((\\,|[^,])+)").unwrap(); } match RE.captures(text.as_str()) { Some(captures) => { if captures.len() < 3 { Err(Error::BadParse) } else { - let command = captures.get(1).unwrap().as_str().to_string(); - let args = captures - .get(2) - .unwrap() - .as_str() - .split(',') - .map(|s| s.trim().to_string()) - .collect(); + let command = captures[1].to_string(); + let args = &captures[2]; + let args = ARGS_RE.captures_iter(args).map(|captures| { + captures[1] + .replace("\\,", ",") + .trim() + .to_string() + }).collect(); Ok(Message { command, args }) } } @@ -117,9 +134,14 @@ mod test { use super::*; #[test] fn test_parse() -> Result<()> { + // Simple test let text = "COMMAND: arg1, arg2"; let msg = Message::parse(text.to_string())?; assert_eq!(msg!(COMMAND, "arg1", "arg2"), msg); + // With backtick delimited arguments + let text = "COMMAND: arg1\\, comment, arg2"; + let msg = Message::parse(text.to_string())?; + assert_eq!(msg!(COMMAND, "arg1, comment", "arg2"), msg); Ok(()) } #[test]