use crate:: { // Internal code character, api, tokenise, UnwrapOrExit, //Libs Mutex, Arc, HashMap, VecDeque, info, warn, debug, }; // Parsing character related instructions // TODO only send relevant tokens #[allow(unused_variables)] pub fn character_parse ( index: usize, tokens: &[tokenise::Token], character_name: String, characters: &Arc>>, happening_queue: &Arc>>, ) -> Result { let mut sum_index: usize = index; let characters_hashmap = characters.lock().unwrap_or_exit("Characters Mutex was poisoned",2); if character_name.to_lowercase() != "narrator" && ! characters_hashmap.contains_key(&character_name) { return Err((format!("Character {character_name} does not exist"),sum_index + 1)); } drop(characters_hashmap); // Ensure the index is valid (the index is not beyond the vector) let keyword = tokenise::get_keyword_token(tokens, sum_index) .map_err(|err| (err, sum_index))?; match keyword.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}"); sum_index += 1; let output = tokenise::get_string_token(tokens, sum_index) .map_err(|err| (err, index))?; debug!("Saying {output}"); api::modify_data(happening_queue, "output".to_string(), output, character_name, vec![]); }, // 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 = tokenise::get_keyword_token(tokens, sum_index) .map_err(|err| (err, index))?; sum_index += 1; let string = tokenise::get_string_token(tokens, sum_index) .map_err(|err| (err, index))?; info!("CHANGE command with character {character_name} feature {feature}"); let mut characters = characters.lock().unwrap_or_exit("Character Mutex was poisoned",3); if let Some(character) = characters.get_mut(&character_name) && character.set_field(&feature, &string) .is_err() { warn!("Feature {feature} does not exist") } drop(characters); api::modify_data(happening_queue, "change".to_string(), String::new(), character_name, vec![]); }, // These two are mainly just actions performed by the frontend client, so just tell the client to move/animate // the character and not much other processing needed on the serverside "to"|"animate" => { sum_index += 1; let content = tokenise::get_keyword_token(tokens, sum_index) .map_err(|err| (err, index))?; api::modify_data(happening_queue, keyword.to_lowercase(), content, character_name, vec![]); }, // Catch all condition, if the instruction is unrecognised as a // character command _ => return Err((format!("Invalid command: {keyword}"),sum_index)), } sum_index += 1; Ok(sum_index) }