Clippy lint fixing

This commit is contained in:
2026-05-14 15:31:48 +01:00
parent 7b9d52e94d
commit a55053dc97
5 changed files with 67 additions and 55 deletions
+13
View File
@@ -3,6 +3,19 @@ name = "happening-server"
version = "0.1.0" version = "0.1.0"
edition = "2024" edition = "2024"
[lints.clippy]
cargo = { level = "warn", priority = -1 }
multiple_crate_versions = { level = "allow" }
correctness = { level = "deny", priority = -1 }
nursery = { level = "deny", priority = -1 }
option_if_let_else = { level = "allow" }
pedantic = { level = "deny", priority = -1 }
perf = { level = "deny", priority = -1 }
style = { level = "deny", priority = -1 }
unwrap_used = "deny"
[dependencies] [dependencies]
env_logger = "0.11.10" env_logger = "0.11.10"
log = "0.4.29" log = "0.4.29"
+5 -5
View File
@@ -49,7 +49,7 @@ pub async fn api_process
// Perform this code on a GET request // Perform this code on a GET request
.map(|state: Arc<Mutex<DataToSend>>, tx_handle: Sender<(bool,usize)>| .map(|state: Arc<Mutex<DataToSend>>, tx_handle: Sender<(bool,usize)>|
{ {
debug!("GET: {:?}", state); debug!("GET: {state:?}");
let reply = state.as_ref(); let reply = state.as_ref();
let _ = tx_handle.send((true,0)); let _ = tx_handle.send((true,0));
warp::reply::json(&reply) // Send the reply data (data_to_send formatted as JSON) warp::reply::json(&reply) // Send the reply data (data_to_send formatted as JSON)
@@ -60,9 +60,9 @@ pub async fn api_process
.and(characters_filter) .and(characters_filter)
.map(|name: String, characters: Arc<Mutex<HashMap<String, character::Character>>>| .map(|name: String, characters: Arc<Mutex<HashMap<String, character::Character>>>|
{ {
let map = characters.lock().unwrap(); // TODO remove unwrap let map = characters.lock().unwrap(); // TODO eh
let reply = map.get(&name).unwrap(); let reply = map.get(&name).unwrap(); // TODO eh
debug!("GET: name: {}", name); debug!("GET: name: {name}");
warp::reply::json(&reply) warp::reply::json(&reply)
}).boxed(); }).boxed();
let choice = warp::path("choice") let choice = warp::path("choice")
@@ -70,7 +70,7 @@ pub async fn api_process
.and(warp::body::json()) .and(warp::body::json())
.and(tx_filter2) .and(tx_filter2)
.map(|index: usize, tx_handle: Sender<(bool,usize)>| { .map(|index: usize, tx_handle: Sender<(bool,usize)>| {
debug!("Choice: {}", index); debug!("Choice: {index}");
let _ = tx_handle.send((true,index)); let _ = tx_handle.send((true,index));
let reply = "ack"; let reply = "ack";
warp::reply::json(&reply) warp::reply::json(&reply)
+4 -4
View File
@@ -32,20 +32,20 @@ pub struct Character
shoes: String, shoes: String,
} }
pub async fn character_parse(archive: &mut ZipArchive<File>) pub fn character_parse(archive: &mut ZipArchive<File>)
-> Result<Arc<Mutex<HashMap<String, Character>>>,String> -> Result<Arc<Mutex<HashMap<String, Character>>>,String>
{ {
// Get the JSON file to a string // Get the JSON file to a string
let mut characters_file = archive.by_name("characters.json") let mut characters_file = archive.by_name("characters.json")
.map_err (|err| format!("Unable to read story file: {}",err))?; .map_err (|err| format!("Unable to read story file: {err}"))?;
let mut file_contents = String::new(); let mut file_contents = String::new();
characters_file.read_to_string(&mut file_contents) characters_file.read_to_string(&mut file_contents)
.map_err (|err| format!("Unable to read story file to string: {}",err))?; .map_err (|err| format!("Unable to read story file to string: {err}"))?;
// Serialise this to a HashMap // Serialise this to a HashMap
let characters: HashMap<String, Character> = let characters: HashMap<String, Character> =
serde_json::from_str(&file_contents) serde_json::from_str(&file_contents)
.expect("JSON was not well-formatted"); .expect("JSON was not well-formatted");
debug!("{:?}",characters); debug!("{characters:?}");
Ok(Arc::new(Mutex::new(characters))) Ok(Arc::new(Mutex::new(characters)))
} }
+22 -22
View File
@@ -1,5 +1,6 @@
use std:: use std::
{ {
process::exit,
env::args, env::args,
fs::File, fs::File,
io::Read, io::Read,
@@ -28,7 +29,6 @@ mod character;
mod config; mod config;
mod api; mod api;
#[warn(clippy::all, clippy::pedantic)]
#[tokio::main] #[tokio::main]
async fn main() async fn main()
{ {
@@ -41,38 +41,38 @@ async fn main()
.unwrap_or_else .unwrap_or_else
(|| { (|| {
error!("No filename specified"); error!("No filename specified");
std::process::exit(5); exit(5);
}); });
let file = File::open(format!("../stories/{}",file_name)) let file = File::open(format!("../stories/{file_name}"))
.unwrap_or_else .unwrap_or_else
(|err| { (|err| {
error!("Failed to open file: {}", err); error!("Failed to open file: {err}");
std::process::exit(2); exit(2);
}); });
let mut archive = ZipArchive::new(file) let mut archive = ZipArchive::new(file)
.unwrap_or_else .unwrap_or_else
(|err| { (|err| {
error!("Failed to open archive: {}", err); error!("Failed to open archive: {err}");
std::process::exit(3); exit(3);
}); });
// Setup the characters hashmap which will store each character in it as a Character struct // Setup the characters hashmap which will store each character in it as a Character struct
let characters = match character::character_parse(&mut archive).await let characters = match character::character_parse(&mut archive)
{ {
Ok(result) => Ok(result) =>
{ {
debug!("{:?}", result); debug!("{result:?}");
result result
}, },
Err(error) => Err(error) =>
{ {
error!("{}",error); error!("{error}");
std::process::exit(3); exit(3);
}, },
}; };
// Initialise the data strcut that will be sent out during API GET requests // Initialise the data strcut that will be sent out during API GET requests
let data_to_send = Arc::new(Mutex::new(api::DataToSend let data_to_send = Arc::new(Mutex::new(api::DataToSend
{ {
action_type: "begin".to_string(), action_type: "begin".to_owned(),
content: String::new(), content: String::new(),
character: String::new(), character: String::new(),
choices: vec![], choices: vec![],
@@ -83,7 +83,7 @@ async fn main()
// Make clones of the data Arc for the two processes // Make clones of the data Arc for the two processes
let data_clone1 = Arc::clone(&data_to_send); let data_clone1 = Arc::clone(&data_to_send);
let characters_clone1 = Arc::clone(&characters); let characters_clone1 = Arc::clone(&characters);
let tx_clone = tx.clone(); let tx_clone = tx;
// Spawn a thread for warp api server // Spawn a thread for warp api server
tokio::spawn( tokio::spawn(
async move { async move {
@@ -97,15 +97,15 @@ async fn main()
let mut story_file = archive.by_name("story.ha") let mut story_file = archive.by_name("story.ha")
.unwrap_or_else .unwrap_or_else
(|err| { (|err| {
error!("Unable to read story file: {}",err); error!("Unable to read story file: {err}");
std::process::exit(4); exit(4);
}); });
let mut file_contents = String::new(); let mut file_contents = String::new();
story_file.read_to_string(&mut file_contents) story_file.read_to_string(&mut file_contents)
.unwrap_or_else .unwrap_or_else
(|err| { (|err| {
error!("Unable to read story file to string: {}",err); error!("Unable to read story file to string: {err}");
std::process::exit(5); exit(5);
}); });
// Tokenise story file // Tokenise story file
let tokens: Vec<&str> = file_contents let tokens: Vec<&str> = file_contents
@@ -115,12 +115,12 @@ async fn main()
{ {
warn!("No END statement, story may exit unexpectedly"); warn!("No END statement, story may exit unexpectedly");
} }
debug!("{:?}", tokens); debug!("{tokens:?}");
let data_clone2 = Arc::clone(&data_to_send); let data_clone2 = Arc::clone(&data_to_send);
let characters_clone2 = Arc::clone(&characters); let characters_clone2 = Arc::clone(&characters);
// Run the parsing process for the DSL // Run the parsing process for the DSL
match parsing::token_parse(&tokens, characters_clone2, data_clone2, &rx).await match parsing::token_parse(&tokens, characters_clone2, &data_clone2, &rx)
{ {
// Exit with error or success // Exit with error or success
Ok(()) => Ok(()) =>
@@ -133,12 +133,12 @@ async fn main()
// Manually unlock the mutex // Manually unlock the mutex
std::mem::drop(data); std::mem::drop(data);
let _ = rx.recv(); // Wait for the client to respond let _ = rx.recv(); // Wait for the client to respond
std::process::exit(0); exit(0);
}, },
Err(error) => Err(error) =>
{ {
error!("{}", error); error!("{error}");
std::process::exit(1); exit(1);
}, },
} }
} }
+22 -23
View File
@@ -18,10 +18,10 @@ use crate::
// Parse the tokens in a file // Parse the tokens in a file
// Returns success or an error string // Returns success or an error string
pub async fn token_parse( pub fn token_parse(
tokens: &Vec<&str>, tokens: &Vec<&str>,
characters: Arc<Mutex<HashMap::<String, character::Character>>>, characters: Arc<Mutex<HashMap::<String, character::Character>>>,
data_to_send: Arc<Mutex<api::DataToSend>>, data_to_send: &Arc<Mutex<api::DataToSend>>,
rx: &Receiver<(bool,usize)>, rx: &Receiver<(bool,usize)>,
) -> Result<(),String> ) -> Result<(),String>
{ {
@@ -31,7 +31,7 @@ pub async fn token_parse(
{ {
warn!("Some issue with api"); warn!("Some issue with api");
// TOD eh? // TOD eh?
}; }
info!("Client has connected"); info!("Client has connected");
// Run an infinite loop // Run an infinite loop
'parse_loop: loop 'parse_loop: loop
@@ -40,14 +40,14 @@ pub async fn token_parse(
let token = tokens let token = tokens
.get(index) .get(index)
.ok_or_else(|| "File unexpectedly reached termination point".to_string())?; .ok_or_else(|| "File unexpectedly reached termination point".to_string())?;
debug!("{}: {}",index, token); debug!("{index}: {token}");
// The instructions are related to characters // The instructions are related to characters
if token.starts_with('@') if token.starts_with('@')
{ {
let character_name: String = token.chars().skip(1).collect(); let character_name: String = token.chars().skip(1).collect();
debug!("Doing something with a character: {}", character_name); debug!("Doing something with a character: {character_name}");
// The index is incremented to after the character's instructions // The index is incremented to after the character's instructions
index = match character_parse(index+1, tokens, character_name, &characters, &data_to_send).await index = match character_parse(index+1, tokens, character_name, &characters, &data_to_send)
{ {
Ok(increment) => increment, Ok(increment) => increment,
Err(error) => return Err(error), Err(error) => return Err(error),
@@ -65,7 +65,7 @@ pub async fn token_parse(
}, },
"choice" => "choice" =>
{ {
let (_,jump_points) = match choice_parse(index+1, tokens, &data_to_send).await let (_,jump_points) = match choice_parse(index+1, tokens, &data_to_send)
{ {
Ok((increment,jump_point)) => (increment,jump_point), Ok((increment,jump_point)) => (increment,jump_point),
Err(error) => return Err(error), Err(error) => return Err(error),
@@ -76,13 +76,13 @@ pub async fn token_parse(
Ok((_,choice)) => (None::<bool>, choice), Ok((_,choice)) => (None::<bool>, choice),
Err(err) => Err(err) =>
{ {
warn!("Error receiving choice from client, defaulting to choice 0 {}", err); warn!("Error receiving choice from client, defaulting to choice 0 {err}");
(None::<bool>, 0) (None::<bool>, 0)
} }
}; };
index = jump_points[choice]; index = jump_points[choice];
info!("CHOICE command with {} choices",jump_points.len()); info!("CHOICE command with {} choices",jump_points.len());
debug!("{:?} {} {}",jump_points, choice, index); debug!("{jump_points:?} {choice} {index}");
continue 'parse_loop continue 'parse_loop
}, },
"or" => "or" =>
@@ -91,7 +91,7 @@ pub async fn token_parse(
index += match strings::closing_char(&tokens[index..], '{','}') // TODO eh index += match strings::closing_char(&tokens[index..], '{','}') // TODO eh
{ {
Ok(index) => index, Ok(index) => index,
Err(_) => return Err(String::from("Unable to find closing brace to OR command")), Err(()) => return Err(String::from("Unable to find closing brace to OR command")),
}; };
continue continue
}, },
@@ -102,20 +102,19 @@ pub async fn token_parse(
}, },
_ => _ =>
{ {
warn!("Invalid command: {}", token); warn!("Invalid command: {token}");
}
} }
};
} }
if rx.recv().is_err() if rx.recv().is_err()
{ {
warn!("Some issue with api"); warn!("Some issue with api");
continue
} }
} }
} }
// Parse the options in a choice clause and returns the idexes of the code blocks // Parse the options in a choice clause and returns the idexes of the code blocks
async fn choice_parse fn choice_parse
( (
index: usize, index: usize,
tokens: &[&str], tokens: &[&str],
@@ -141,18 +140,19 @@ async fn choice_parse
choice_indeces.push(sum_index+2); choice_indeces.push(sum_index+2);
sum_index += strings::closing_char(&tokens[sum_index..], '{','}').unwrap() + 1; //TODO eh sum_index += strings::closing_char(&tokens[sum_index..], '{','}').unwrap() + 1; //TODO eh
} }
debug!("{:?}", choices); debug!("{choices:?}");
let mut data = data_to_send.lock().unwrap(); let mut data = data_to_send.lock().unwrap();
data.action_type = String::from("choice"); data.action_type = String::from("choice");
data.content = "".to_string(); data.content = String::new();
data.character = "".to_string(); data.character = String::new();
data.choices = choices; //TODO data.choices = choices; //TODO
Ok((sum_index + 1, choice_indeces)) Ok((sum_index + 1, choice_indeces))
} }
// Parsing character related instructions // Parsing character related instructions
// TODO only send relevant tokens // TODO only send relevant tokens
#[allow(unused_variables)] async fn character_parse #[allow(unused_variables)]
fn character_parse
( (
index: usize, index: usize,
tokens: &Vec<&str>, tokens: &Vec<&str>,
@@ -172,18 +172,17 @@ async fn choice_parse
// to the client // to the client
"says" => "says" =>
{ {
info!("SAYS command with character {}", character_name); info!("SAYS command with character {character_name}");
match strings::extract_quoted(&tokens[sum_index+1..]) // TODO increment to after the string match strings::extract_quoted(&tokens[sum_index+1..]) // TODO increment to after the string
{ {
Some((output_string, counter)) => Some((output_string, counter)) =>
{ {
debug!("{}", output_string); debug!("{output_string}");
sum_index += counter; sum_index += counter;
debug!("{}",sum_index);
let mut data = data_to_send.lock().unwrap(); let mut data = data_to_send.lock().unwrap();
data.action_type = String::from("output"); data.action_type = String::from("output");
data.content = output_string; data.content = output_string;
data.character = character_name.clone(); data.character = character_name;
data.choices = vec![]; data.choices = vec![];
}, },
None => return Err(String::from("Unable to read string")), None => return Err(String::from("Unable to read string")),
@@ -191,7 +190,7 @@ async fn choice_parse
}, },
// Catch all condition, if the instruction is unrecognised as a // Catch all condition, if the instruction is unrecognised as a
// character command // character command
_ => return Err(format!("Invalid command: {}", token)), _ => return Err(format!("Invalid command: {token}")),
} }
sum_index += 1; sum_index += 1;
Ok(sum_index) Ok(sum_index)