diff --git a/.gitignore b/.gitignore index d0935c9..2b032ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /server/target *.swp .venv +.~* diff --git a/report.odt b/report.odt new file mode 100644 index 0000000..eefef77 Binary files /dev/null and b/report.odt differ diff --git a/server/src/main.rs b/server/src/main.rs index e1a6658..65c28df 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -127,7 +127,7 @@ async fn main() Ok(()) => { info!("Program exited successfully"); - let mut data = data_to_send.lock().unwrap(); + let mut data = data_to_send.lock().unwrap(); // TODO eh? data.action_type = String::from("end"); data.content = String::new(); data.character = String::new(); diff --git a/server/src/parsing.rs b/server/src/parsing.rs index 8670c3e..b33240b 100644 --- a/server/src/parsing.rs +++ b/server/src/parsing.rs @@ -1,5 +1,4 @@ use std::collections::HashMap; -mod strings; use crate:: { // Internal code @@ -15,6 +14,8 @@ use crate:: warn, }; +mod strings; +mod character_parse; // Parse the tokens in a file // Returns success or an error string @@ -47,10 +48,14 @@ pub fn token_parse( let character_name: String = token.chars().skip(1).collect(); debug!("Doing something with a character: {character_name}"); // The index is incremented to after the character's instructions - index = match character_parse(index+1, tokens, character_name, &characters, &data_to_send) + index = match character_parse::character_parse(index+1, tokens, character_name, &characters, &data_to_send) { Ok(increment) => increment, - Err(error) => return Err(error), + Err((err,increment)) => + { + warn!("{err}"); + increment + }, }; } // Miscelleneous instructions @@ -148,76 +153,3 @@ fn choice_parse data.choices = choices; //TODO Ok((sum_index + 1, choice_indeces)) } - -// Parsing character related instructions -// TODO only send relevant tokens -#[allow(unused_variables)] -fn character_parse -( - index: usize, - tokens: &Vec<&str>, - character_name: String, - characters: &Arc>>, - data_to_send: &Arc>, -) -> Result -{ - let mut sum_index: usize = index; - // Ensure the index is valid (the index is not beyond the vector) - let token = tokens - .get(sum_index) - .ok_or_else(|| "File unexpectedly reached termination point".to_string())?; - match token.to_lowercase().as_str() - { - // The character is saying something, so grab the text and pass it - // to the client - "says" => - { - info!("SAYS command with character {character_name}"); - match strings::extract_quoted(&tokens[sum_index+1..]) - { - Some((output_string, counter)) => - { - debug!("{output_string}"); - sum_index += counter; - let mut data = data_to_send.lock().unwrap(); - data.action_type = String::from("output"); - data.content = output_string; - data.character = character_name; - data.choices = vec![]; - }, - None => return Err("Unable to read output string".to_string()), - } - }, - // Change the property of the selected character eg @tim CHANGE name "Bill Buffins" - // will change the character with ID tim to "Bill Buffins"; a character's ID cannot change - "change" => - { - sum_index += 1; - let feature = tokens - .get(sum_index) - .ok_or_else(|| "File unexpectedly reached termination point".to_string())?; - let output_string: String; - (output_string, sum_index) = match strings::extract_quoted(&tokens[sum_index+1..]) - { - Some((string,counter)) => (string,sum_index+counter), - None => return Err("Unable to parse property to change character".to_string()), - }; - info!("CHANGE command with character {character_name} feature {feature}"); - let mut characters = characters.lock().expect("Data cannot be unlocked"); - if let Some(character) = characters.get_mut(&character_name) - { - if character.set_field(feature, &output_string) - .is_err() { warn!("Feature {feature} does not exist") }; - } - let mut data = data_to_send.lock().unwrap(); - data.action_type = String::from("change"); - data.content = String::new(); - data.character = character_name; - }, - // Catch all condition, if the instruction is unrecognised as a - // character command - _ => return Err(format!("Invalid command: {token}")), - } - sum_index += 1; - Ok(sum_index) -} diff --git a/server/src/parsing/character_parse.rs b/server/src/parsing/character_parse.rs new file mode 100644 index 0000000..d298c71 --- /dev/null +++ b/server/src/parsing/character_parse.rs @@ -0,0 +1,88 @@ +use super::strings; +use crate:: +{ + // Internal code + character, + api, + //Libs + Mutex, + Arc, + HashMap, + info, + warn, + debug, +}; + +// Parsing character related instructions +// TODO only send relevant tokens +#[allow(unused_variables)] +pub fn character_parse +( + index: usize, + tokens: &Vec<&str>, + character_name: String, + characters: &Arc>>, + data_to_send: &Arc>, +) -> Result +{ + let mut sum_index: usize = index; + // Ensure the index is valid (the index is not beyond the vector) + let token = tokens + .get(sum_index) + .ok_or_else(|| ("File unexpectedly reached termination point".to_string(), sum_index))?; + match token.to_lowercase().as_str() + { + // The character is saying something, so grab the text and pass it + // to the client + "says" => + { + info!("SAYS command with character {character_name}"); + match strings::extract_quoted(&tokens[sum_index+1..]) + { + Some((output_string, counter)) => + { + debug!("{output_string}"); + sum_index += counter; + let mut data = data_to_send.lock().unwrap(); + data.action_type = String::from("output"); + data.content = output_string; + data.character = character_name; + data.choices = vec![]; + }, + None => return Err(("Unable to read output string".to_string(), sum_index)), + } + }, + // Change the property of the selected character eg @tim CHANGE name "Bill Buffins" + // will change the character with ID tim to "Bill Buffins"; a character's ID cannot change + "change" => + { + sum_index += 1; + let feature = tokens + .get(sum_index) + .ok_or_else(|| ("File unexpectedly reached termination point".to_string(), sum_index))?; + let output_string: String; + (output_string, sum_index) = match strings::extract_quoted(&tokens[sum_index+1..]) + { + Some((string,counter)) => (string,sum_index+counter), + None => return Err(("Unable to parse property to change character".to_string(),sum_index)), + }; + info!("CHANGE command with character {character_name} feature {feature}"); + let mut characters = characters.lock().expect("Data cannot be unlocked"); + if let Some(character) = characters.get_mut(&character_name) + { + if character.set_field(feature, &output_string) + .is_err() { warn!("Feature {feature} does not exist") }; + } + let mut data = data_to_send.lock().unwrap(); // TODO eh? + data.action_type = String::from("change"); + data.content = String::new(); + data.character = character_name; + }, + // Catch all condition, if the instruction is unrecognised as a + // character command + _ => return Err((format!("Invalid command: {token}"),sum_index)), + } + sum_index += 1; + Ok(sum_index) +} +