Files
happening/server/src/parsing/character_parse.rs
T
deadvey ee34493895 Changed the data_to_send to be a stack so many lines of code can
be pre-processed before the user interacts.
When the /happening api is called it just dequeues the front item
2026-05-19 19:23:19 +01:00

88 lines
2.9 KiB
Rust

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<Mutex<HashMap::<String, character::Character>>>,
happening_queue: &Arc<Mutex<VecDeque<api::DataToSend>>>,
) -> Result<usize,(String,usize)>
{
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)
}