Allow for escaped commas in message

This commit is contained in:
Dane Johnson 2022-10-12 14:31:23 -05:00
parent daedfe72d0
commit c41bf83eb8
2 changed files with 36 additions and 11 deletions

View File

@ -42,6 +42,8 @@ impl Client {
} }
} }
async fn handle_client_msg(&mut self, msg: Message) { 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() { match msg.command.as_str() {
"HOST" => { "HOST" => {
let room_code = self.global_state.code_generator.lock().await.generate(); 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) { async fn handle_server_msg(&mut self, msg: Message) {
todo!(); // Forward the message via websocket
self.ws.send(msg).await.unwrap();
} }
} }

View File

@ -22,23 +22,40 @@ pub enum Error {
} }
impl Message { impl Message {
// pub fn parse(text: String) -> Result<Message> {
// 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<Message> { pub fn parse(text: String) -> Result<Message> {
use regex::Regex;
lazy_static! { 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()) { match RE.captures(text.as_str()) {
Some(captures) => { Some(captures) => {
if captures.len() < 3 { if captures.len() < 3 {
Err(Error::BadParse) Err(Error::BadParse)
} else { } else {
let command = captures.get(1).unwrap().as_str().to_string(); let command = captures[1].to_string();
let args = captures let args = &captures[2];
.get(2) let args = ARGS_RE.captures_iter(args).map(|captures| {
.unwrap() captures[1]
.as_str() .replace("\\,", ",")
.split(',') .trim()
.map(|s| s.trim().to_string()) .to_string()
.collect(); }).collect();
Ok(Message { command, args }) Ok(Message { command, args })
} }
} }
@ -117,9 +134,14 @@ mod test {
use super::*; use super::*;
#[test] #[test]
fn test_parse() -> Result<()> { fn test_parse() -> Result<()> {
// Simple test
let text = "COMMAND: arg1, arg2"; let text = "COMMAND: arg1, arg2";
let msg = Message::parse(text.to_string())?; let msg = Message::parse(text.to_string())?;
assert_eq!(msg!(COMMAND, "arg1", "arg2"), msg); 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(()) Ok(())
} }
#[test] #[test]