Cleaned code up a bit

TODD:
make colour an enum
make unwrap_or_exit return the error
This commit is contained in:
2026-05-17 15:44:01 +01:00
parent 13049309b2
commit dd04399784
11 changed files with 54 additions and 71 deletions
+11
View File
@@ -462,6 +462,7 @@ dependencies = [
"env_logger",
"log",
"serde",
"serde-patch",
"serde_json",
"tokio",
"warp",
@@ -969,6 +970,16 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "serde-patch"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ba8dcbff6509fa9394810d943e0e9d486a4256c23f6fcea8a58865fbe8260c4"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "serde_core"
version = "1.0.228"
+1
View File
@@ -26,6 +26,7 @@ unwrap_used = "warn"
env_logger = "0.11.10"
log = "0.4.29"
serde = { version = "1.0.228", features = ["derive"] }
serde-patch = "0.2.3"
serde_json = "1.0.149"
tokio = { version = "1.51.0", features = ["rt-multi-thread","macros"] }
warp = { version = "0.4.2", features = ["server"] }
+7 -25
View File
@@ -7,6 +7,7 @@ use crate::{
info,
Deserialize,
Serialize,
apply_mut,
Mutex,
Arc,
};
@@ -27,7 +28,7 @@ pub struct Character
torso_shape: String,
arm_shape: String,
leg_shape: String,
hair_color: String,
hair_color: String, // TODO RGB enum
clothing: Clothing,
}
#[derive(Debug,Deserialize,Serialize,Clone,Default)]
@@ -39,30 +40,11 @@ pub struct Clothing
shoes: String,
}
impl Character {
// Big ass ugly function because rust doesn't support referencing struct entries by string
pub fn set_field(&mut self, field: &str, value: &str) -> Result<(), ()> {
match field {
"name" => self.name = value.to_string(),
"gender" => self.gender = value.to_string(),
"eye_color" => self.eye_color = value.to_string(),
"pronoun_subject" => self.pronoun_subject = value.to_string(),
"pronoun_object" => self.pronoun_object = value.to_string(),
"pronoun_deppos" => self.pronoun_deppos = value.to_string(),
"pronoun_indpos" => self.pronoun_indpos = value.to_string(),
"pronoun_reflex" => self.pronoun_reflex = value.to_string(),
"head_shape" => self.head_shape = value.to_string(),
"hair_style" => self.hair_style = value.to_string(),
"torso_shape" => self.torso_shape = value.to_string(),
"arm_shape" => self.arm_shape = value.to_string(),
"leg_shape" => self.leg_shape = value.to_string(),
"hair_color" => self.hair_color = value.to_string(),
"clothing.top" => self.clothing.top = value.to_string(),
"clothing.bottom" => self.clothing.bottom = value.to_string(),
"clothing.shoes" => self.clothing.shoes = value.to_string(),
_ => return Err(()),
}
// Big ass ugly match case
pub fn set_field(&mut self, field: &str, value: &str) -> Result<(), String> {
let patch = format!("{{ \"{field}\": \"{value}\" }}");
apply_mut(self, patch)
.map_err(|_| "Invalid field".to_string())?;
Ok(())
}
}
+7 -16
View File
@@ -27,6 +27,7 @@ use serde::
Serialize
};
use serde_json::json;
use serde_patch::apply_mut;
use zip::
{
ZipArchive,
@@ -51,17 +52,9 @@ async fn main()
exit(10);
});
let file = File::open(format!("../stories/{file_name}")) // Get the file
.unwrap_or_else
(|err| {
error!("Failed to open file: {err}");
exit(11);
});
.unwrap_or_exit("Failed to read file.", 11);
let mut archive = ZipArchive::new(file) // Open the archive
.unwrap_or_else
(|err| {
error!("Failed to open archive: {err}");
exit(12);
});
.unwrap_or_exit("Failed to open archive", 12);
// Setup the characters hashmap which will store each character in it as a Character struct
let characters = match character::character_parse(&mut archive)
{
@@ -102,11 +95,7 @@ async fn main()
// Read the file and split it into tokens
// file read from a zip file /story.ha
let mut story_file = archive.by_name("story.ha")
.unwrap_or_else
(|err| {
error!("Unable to read story file: {err}");
exit(14);
});
.unwrap_or_exit("Unable to read story file", 14);
let mut file_contents = String::new();
story_file.read_to_string(&mut file_contents)
.unwrap_or_else
@@ -121,11 +110,13 @@ async fn main()
{
warn!("No END statement, story may exit unexpectedly");
}
let (tokens, labels,_) = tokenise::tokenise(&space_seperated, 0).unwrap();
let (tokens, labels,_) = tokenise::tokenise(&space_seperated, 0)
.unwrap_or_exit("Unable to tokenise data", 15);
debug!("{tokens:?}");
let data_clone2 = Arc::clone(&data_to_send);
let characters_clone2 = Arc::clone(&characters);
// Run the parsing process for the DSL
info!("DSL parsing begun");
match parsing::token_parse(&tokens, &characters_clone2, &data_clone2, &rx)
{
// Exit with error or success
+1 -2
View File
@@ -20,13 +20,12 @@ mod character_parse;
// Parse the tokens in a file
// Returns success or an error string
pub fn token_parse(
tokens: &Vec<tokenise::Token>,
tokens: &[tokenise::Token],
characters: &Arc<Mutex<HashMap::<String, character::Character>>>,
data_to_send: &Arc<Mutex<api::DataToSend>>,
rx: &Receiver<(bool,usize,String)>,
) -> Result<(),String>
{
info!("DSL parsing begun");
let mut index: usize = 0;
if rx.recv().is_err()
{
+3 -3
View File
@@ -20,7 +20,7 @@ use crate::
pub fn character_parse
(
index: usize,
tokens: &Vec<tokenise::Token>,
tokens: &[tokenise::Token],
character_name: String,
characters: &Arc<Mutex<HashMap::<String, character::Character>>>,
data_to_send: &Arc<Mutex<api::DataToSend>>,
@@ -44,7 +44,7 @@ pub fn character_parse
let output = tokenise::get_string_token(tokens, sum_index)
.map_err(|err| (err, index))?;
debug!("Saying {output}");
api::modify_data(data_to_send, "output".to_string(), output.to_string(), character_name, vec![]);
api::modify_data(data_to_send, "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
@@ -71,7 +71,7 @@ pub fn character_parse
sum_index += 1;
let content = tokenise::get_string_token(tokens, sum_index)
.map_err(|err| (err, index))?;
api::modify_data(data_to_send, token.to_lowercase(), content.to_string(), character_name, vec![]);
api::modify_data(data_to_send, token.to_lowercase(), content, character_name, vec![]);
},
// Catch all condition, if the instruction is unrecognised as a
// character command
+20 -24
View File
@@ -6,28 +6,27 @@ use crate::
#[derive(Debug, Clone)]
pub enum Token
{
Null,
String(String),
Object(Vec<Token>),
Object(Vec<Self>),
}
pub fn get_string_token(tokens: &Vec<Token>, index: usize)
pub fn get_string_token(tokens: &[Token], index: usize)
-> Result<String, String>
{
match tokens.get(index) {
Some(Token::String(s)) => return Ok(s.clone()),
Some(_) => return Err("Unexpected token".to_string()),
None => return Err("File unexpectedly reached termination point".to_string()),
Some(Token::String(s)) => Ok(s.clone()),
Some(_) => Err("Unexpected token".to_string()),
None => Err("File unexpectedly reached termination point".to_string()),
}
}
pub fn get_object_token(tokens: &Vec<Token>, index: usize)
pub fn get_object_token(tokens: &[Token], index: usize)
-> Result<&Vec<Token>, String>
{
match tokens.get(index) {
Some(Token::Object(v)) => return Ok(v),
Some(_) => return Err("Unexpected token".to_string()),
None => return Err("File unexpectedly reached termination point".to_string()),
Some(Token::Object(v)) => Ok(v),
Some(_) => Err("Unexpected token".to_string()),
None => Err("File unexpectedly reached termination point".to_string()),
}
}
@@ -42,19 +41,19 @@ pub fn tokenise(space_seperated: &Vec<&str>, mut index: usize)
while index < space_seperated.len()
{
let mut item = space_seperated[index].to_string();
let mut object: Vec<Token>;
if item.starts_with("\"")
let object: Vec<Token>;
if item.starts_with('"') // TODO support '
{
(index, item) = match tokenise_string(&space_seperated, index)
(index, item) = match tokenise_string(space_seperated, index)
{
Some((index,item)) => (index, item),
Some((index,item)) => (index,item),
None => exit(1),
};
tokenised_data.push(Token::String(item));
}
else if item == "{"
{
(object, labels, index) = match tokenise(&space_seperated, index+1) // !WARNING! recursive call
(object, labels, index) = match tokenise(space_seperated, index+1) // !WARNING! recursive call
{
Ok((object,labels,index)) => (object,labels,index),
Err(err) => return Err(err),
@@ -68,10 +67,10 @@ pub fn tokenise(space_seperated: &Vec<&str>, mut index: usize)
else { tokenised_data.push(Token::String(item)); }
index += 1;
}
return Ok((tokenised_data, labels, 0));
Ok((tokenised_data, labels, 0))
}
fn tokenise_string(space_seperated: &Vec<&str>, mut index: usize)
fn tokenise_string(space_seperated: &[&str], mut index: usize)
-> Option<(usize, String)>
{
let mut string = String::new();
@@ -80,18 +79,15 @@ fn tokenise_string(space_seperated: &Vec<&str>, mut index: usize)
string += chars.as_str();
for item in &space_seperated[index+1..]
{
if item.ends_with("\"")
if item.ends_with('"')
{
let mut chars = item.chars();
chars.next_back();
string += format!(" {}", chars.as_str()).as_str();
break
}
else
{
string += format!(" {}", item).as_str();
return Some((index+1,string))
}
string += format!(" {item}").as_str();
index += 1;
}
return Some((index+1,string))
None
}
+2
View File
@@ -4,6 +4,8 @@ use crate::
exit,
};
// TODO support Options
// TODO pass error message back
pub trait UnwrapOrExit<T>
{
fn unwrap_or_exit(self, error_message: &str, error_code: i32) -> T;