From 800bee13da35db0028d74f03fb64ad28f1dcd829 Mon Sep 17 00:00:00 2001 From: deadvey Date: Thu, 30 Apr 2026 12:42:47 +0100 Subject: [PATCH] polished up a bit and got the index offset working --- src/{parsing/.strings.rs.swp => .main.rs.swp} | Bin 12288 -> 12288 bytes src/main.rs | 56 ++++++++++++---- src/parsing.rs | 63 +++++++++--------- src/parsing/strings.rs | 10 ++- stories/story.ha | 3 +- 5 files changed, 84 insertions(+), 48 deletions(-) rename src/{parsing/.strings.rs.swp => .main.rs.swp} (77%) diff --git a/src/parsing/.strings.rs.swp b/src/.main.rs.swp similarity index 77% rename from src/parsing/.strings.rs.swp rename to src/.main.rs.swp index 9b28f4efbdea44d23f98abe8b153b436e97c60f4..049d79cc04efa4a365a12bffb64f218cf7235e08 100644 GIT binary patch literal 12288 zcmYc?2=nw+u+%eRU|?VnU|?8f|0(loX9xqEEdxVJYGO)RY9&YpFV4x#E3MEiNXDy( zfq|h8YM_2{eoCr-QE73Benw(JL26!RUb=p9QL=t+VrHIRQ86KNM&(CCU^E0s41v;; zG+hf`24f>b1CUN-B}D~cp->QW6px0$Xb6mkz-S1JhQMeDjE2By2#kinXb6mu5GW~N zWTV0h2Zz;J_~fnhH{1H&$U28Ip%3=He| z85oxHGcYXRXJDAY&%iL1pMhZtKLbNMKLbMrKLbM!KLbNDKLbM&KLbNBKLdj^KLdj! zKLdk4KLdjlKLf*4J_d%Pd<+Z~d<+Z@d<+b>d<+bdd<+c#co`TT@-i^o=4D{G#mm5O zlb3;^mzRN|hnImNjF*8ygO`DUhnIojDGvj~H68|r<2(!uQ+XH|Ch#yY^z$$<^zkq- z*zqthJmh9zn9a?=FpHakA)lLpfsvbm;UyOX!&5E>hV5Jo40E{{7^ZVEFcfexFhp@N zF!*pWFnDt@FvxN-Ffej4Fl^>zVA#OPz%YT6fuWg`fuWw0fgy~OfkBOvf#Ej?1H&y2 z28Qh%3=Gpb7#Qj}7#Q3*7#MUo7#P$!7#PGk7#M^(7#M!AGcep^XJEL=&cJYu9TL80 z*clj3gTi?Trjt=8kA}c#2#kinXb2465U6F~tYzTjtcB4!44j;t#U&|LRs}`*$*IM~ zR#vGMnI#&An${qh)PkbSypo(eMGd9uS|uHY)S{yNBCu3711G0zQIQ5jM8Vb$WGXJx z48U4Ab5ctb;uUNaiYoMqQj^OxG_4i%^%cSsGfNcG@{1HoGExZ(?3)Vopw_LTO%3esVV0klfOe)C!PB zkV?JejKreEcMG0aS$bY$|B?=%j6>Py&d`W(MacW+Q9>{STntG*qnxar#nhc7Fw9=fMN{GRru=dZ^(9qOWu(eZQ;N;ZTS8%P!EKw-W zEXjbxi9&u6Od|tlH3MgEVo7p_LP26tG1$K)`Pr#?@gQ!hh8mbttfQa?aw|M^igh3k zPR_~COEuC_P%Em?)JrT+%q(F5*%wrr2M$}18JT(M3ee=j0FG3UhvOj{6>Jq8i;}IZ zz&s5#unaT|G_4sJI63u_^K)`ilS?3BpjTXwlUWj9o{?FST3nEroT{M-F%sfPD}}Js zWE-{Ok|H|=TZOdDoYeSaNL&?z(iZ{szyy}QBe)VK`546K~oaQQN>nPMX8A?;Fty{FAb&QlKi5~ z)M9-QU8$FmsH6!>=pp_t{tCH?*{KR88JWcji3-X2xw(mXDGE86d8rDCMd_uvsd>=Q zPEAY!2RF!81&|tWI4NY7C}if9d(>njAOmXsENt%R#BR>(*!&d5zHP$5*?HvhjYT? z+)6=7Ne`4?At_lCRH8$395yMWa?wgbDJeBQGY?&RH6+YH{sL!_)Vvf}z<^3&Ur<>M zNr~Y2bV)2p49O2p1(p2z`U;+TnI)NtIhnB&8}8 zgNpBbP}y4wD&Z9z13VSnT|*R#QVUB{i%W_jj?gHn&?&0WRIpXZEhq*RQW=SPd8s+z zqDWs~A*2GF)q*M%5_59$%M~i~OF;!jL1J++#O9>blJeA4P(cVvAjJ%vsd;7bIr-`7 zsYO;+nR%IzLQP*^!7aZ?Atg1bG(9~tFP)*90h034@)SVJ*EKX5l%t`k55$jUV93o+ z0i`l)Fe5oXFD)}2%7*1u2p5`DtQi<;trcB2b#QvZ{70O4d;T2euB_^R+q*oY0auGe57`$_iR&=rC}m6~jycm#ho`ehcJI literal 12288 zcmYc?2=nw+u+%eRU|?VnU|!wZ@JhxPww@-r}$^D{7{@G~$Z@-r|P^D{8$^D{7r z@G~$x;A3Fe%E!R4f{%e=HXj4S1U?3aGCl@|WIhIlU_J&0Q$7X;Lp}xuEj|VYH9iIg zZaxMEc0L9M7Cr`se^9$L_=aF$jXHTW1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz5ld z2-Grg`sL@PGH}*1aDp*sS!!~8F?jK{UO{PbhK5!_Vo`~vH3KJSH3KJSYEE$~Ol47O zNoi4@LU4X=szzF7USbYZA6PLbr(SY?PEKlai3XGp5-80p(a==TRWQO+Ktof()>c7XNu2={a%uTR zU=0eHd0@JjffMAY+|m*SghdLr3Sp_qR#thb<)Bb2C{0pG%Tq|LC@D%zE{QKJ%`Zt! z(EwRnY^9(UtyWx86sxJAYp38}P?DLSX9MxRokF#OzP>_;zl*;@Voq_s0yLfy74k}R YlTwQmO7ayl^OB2Fb5rw56p|_#06iVf_y7O^ diff --git a/src/main.rs b/src/main.rs index 45cf579..3260184 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,6 @@ use std:: use log:: { info, - trace, warn, debug, }; @@ -20,34 +19,67 @@ mod api; #[tokio::main] async fn main() { + // For debugging env_logger::init(); + // Tx and Rx allow you to pass data between threads let (tx,rx) = mpsc::channel(); + // Initialise the data strcut that will be sent out during API GET requests let data_to_send = Arc::new(Mutex::new(api::DataToSend { - action_type: "initialise".to_string(), + action_type: "begin".to_string(), content: "".to_string(), character: "".to_string(), })); - let data = Arc::clone(&data_to_send); + + // setup the api stuff // + + // Make clones of the data Arc for the two processes + let data_clone1 = Arc::clone(&data_to_send); let tx_clone = tx.clone(); - // Spawn a thread for warp + // Spawn a thread for warp api server tokio::spawn( async move { - api::api_process(data, tx_clone).await; + api::api_process(data_clone1, tx_clone).await; }); - debug!("and continue"); + + + // setup the parsing stuff // + // Setup the characters hashmap which will store each character in it as a Character struct let mut characters = HashMap::::new(); - let file_contents: String = fs::read_to_string("stories/story.ha").unwrap(); - // Split the file contents into tokens + + // Read the file and split it into tokens + let file_contents: String = fs::read_to_string("stories/story.ha") // TODO make this a command line argument + .unwrap_or_else(|err| + { + eprintln!("Failed to read file: {}", err); + std::process::exit(2); + }); let tokens: Vec<&str> = file_contents .split_whitespace() .collect(); + + let data_clone2 = Arc::clone(&data_to_send); // Run the parsing process - let data_clone = Arc::clone(&data_to_send); - match parsing::token_parse(&tokens, &mut characters, data_clone, &rx).await + match parsing::token_parse(&tokens, &mut characters, data_clone2, &rx).await { - Ok(()) => info!("Program exited successfully"), - Err(error) => eprintln!("{}", error), + // Exit with error or success + Ok(()) => + { + info!("Program exited successfully"); + let mut data = data_to_send.lock().unwrap(); + data.action_type = String::from("end"); + data.content = String::new(); + data.character = String::new(); + // Manually unlock the mutex + std::mem::drop(data); + let _ = rx.recv(); // Wait for the client to respond + std::process::exit(0); + }, + Err(error) => + { + eprintln!("{}", error); + std::process::exit(1); + }, } } diff --git a/src/parsing.rs b/src/parsing.rs index 6aabbe6..8c8f3a8 100644 --- a/src/parsing.rs +++ b/src/parsing.rs @@ -1,6 +1,4 @@ use std::collections::HashMap; -use std::time::Duration; -use std::thread; mod strings; use crate:: { @@ -32,9 +30,8 @@ pub async fn token_parse( loop { // If the client hasn't responded then continue (after a short pause) - if rx.try_recv().is_err() + if rx.recv().is_err() { - thread::sleep(Duration::from_millis(300)); continue } // Get the next token @@ -52,17 +49,19 @@ pub async fn token_parse( let new_character = character::Character::new(character_name.clone()); characters.insert(character_name.clone(),new_character); } - println!("Doing something with a character: {}", character_name); + info!("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, &mut characters, &data_to_send, &rx).await { Ok(increment) => increment, Err(error) => return Err(error), - } + }; + continue } // Miscelleneous instructions if token.to_lowercase() == "end" { + info!("END command, exiting"); return Ok(()) // quit } index += 1; @@ -80,35 +79,35 @@ async fn character_parse ) -> Result { let mut sum_index: usize = index; - loop + // Ensure the index is valid (the index is not beyond the vector) + let token = tokens + .get(sum_index) + .ok_or_else(|| "File reached termination point".to_string())?; + match token.to_lowercase().as_str() { - // Ensure the index is valid (the index is not beyond the vector) - let token = tokens - .get(sum_index) - .ok_or_else(|| "File 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" => { - // 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..]) // 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) => - { - debug!("{}", output_string); - let mut data = data_to_send.lock().unwrap(); - data.action_type = String::from("output"); - data.content = output_string; - data.character = character_name.clone(); - }, - None => return Err(String::from("Unable to read string")), - } - }, - // Catch all condition, if the instruction is unrecognised as a - // character command - _ => return Err(String::from(format!("Invalid command: {}", token))), - } - sum_index += 1; + 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.clone(); + }, + None => return Err(String::from("Unable to read string")), + } + }, + // Catch all condition, if the instruction is unrecognised as a + // character command + _ => return Err(String::from(format!("Invalid command: {}", token))), } + sum_index += 1; + Ok(sum_index) } diff --git a/src/parsing/strings.rs b/src/parsing/strings.rs index 67b643b..c6b1053 100644 --- a/src/parsing/strings.rs +++ b/src/parsing/strings.rs @@ -1,8 +1,11 @@ -pub fn extract_quoted(parts: &[&str]) -> Option { // TODO also return a number to increment by +pub fn extract_quoted(parts: &[&str]) -> Option<(String, usize)> { let mut vec_string = Vec::new(); + let mut counter: usize = 0; for part in parts { - if part.chars().next_back().unwrap() == '"' + counter += 1; + // End of the string + if part.chars().next_back().unwrap() == '"' // TODO allow for backslashes and ' { vec_string.push(*part); let final_string: String = vec_string.join(" "); @@ -13,8 +16,9 @@ pub fn extract_quoted(parts: &[&str]) -> Option { // TODO also return a final_string.chars() .count() - 2) .collect(); - return Some(final_string); + return Some((final_string, counter)); } + // Otherwise just add this to the list else { vec_string.push(*part); diff --git a/stories/story.ha b/stories/story.ha index d9f5a16..5ce98b6 100644 --- a/stories/story.ha +++ b/stories/story.ha @@ -1 +1,2 @@ -@tim says "hello to all the world" +@tim says "hello world, it's a good day" +END