From 660f7cad7ed44b18172b6d9b77220f49f010377b Mon Sep 17 00:00:00 2001 From: deadvey Date: Wed, 29 Apr 2026 00:40:29 +0100 Subject: [PATCH] Did a bit of polishing up --- $h | 36 --- .qtcreator/project.json | 30 -- .qtcreator/project.json.user | 294 ------------------- Cargo.lock | 176 +++++++++++ Cargo.toml | 2 + src/api.rs | 48 +-- src/main.rs | 24 +- src/parsing.rs | 138 ++++----- src/{.api.rs.swp => parsing/.strings.rs.swp} | Bin 12288 -> 12288 bytes src/parsing/strings.rs | 3 +- stories/story.ha | 3 +- 11 files changed, 293 insertions(+), 461 deletions(-) delete mode 100644 $h delete mode 100644 .qtcreator/project.json delete mode 100644 .qtcreator/project.json.user rename src/{.api.rs.swp => parsing/.strings.rs.swp} (88%) diff --git a/$h b/$h deleted file mode 100644 index 31f65fb..0000000 --- a/$h +++ /dev/null @@ -1,36 +0,0 @@ -use warp::Filter; -use std::{ - thread, - sync::{Arc, Mutex}, -} -use crate::config; -use serde::{Deserialize, Serialize}; -use crate::mpsc::*; -use tokio::sync::RwLock; -use crate::api; - -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct Data_to_send { - pub action_type: String, - pub content: String, - pub character: String, -} -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct Data_to_receive { - pub response: String, -} - -pub async fn api_process(data_to_send: Arc) -{ - let route = warp::path("happening") - .map({ - let state = Arc::clone(&data_to_send); - move || { - let current_data = state.lock().unwrap().clone(); - warp::reply::json(current_data) - } - }); - warp::serve(routes) - .run(([127, 0, 0, 1],config::API_PORT)); - .await; -} diff --git a/.qtcreator/project.json b/.qtcreator/project.json deleted file mode 100644 index d9860ad..0000000 --- a/.qtcreator/project.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "https://download.qt.io/official_releases/qtcreator/latest/installer_source/jsonschemas/project.json", - "build.configuration": [ - { - "name": "cargo build", - "steps": [ - { - "arguments": [ - "build" - ], - "executable": "cargo", - "workingDirectory": "%{ActiveProject:ProjectDirectory}" - } - ] - } - ], - "files.exclude": [ - ".qtcreator/project.json.user" - ], - "targets": [ - { - "arguments": [ - "run" - ], - "executable": "cargo", - "name": "cargo run", - "workingDirectory": "%{ActiveProject:ProjectDirectory}" - } - ] -} diff --git a/.qtcreator/project.json.user b/.qtcreator/project.json.user deleted file mode 100644 index c285834..0000000 --- a/.qtcreator/project.json.user +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - EnvironmentId - {feb331f8-7617-4b45-82a8-67687dcf787d} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - true - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 0 - 80 - true - true - 1 - 0 - false - true - false - 2 - true - true - 0 - 8 - true - false - 1 - false - true - true - *.md, *.MD, Makefile - false - true - true - - - - ProjectExplorer.Project.PluginSettings - - - true - false - true - true - true - true - - false - - - 0 - true - - true - true - Builtin.DefaultTidyAndClazy - 6 - true - - - - true - - 0 - - - - ProjectExplorer.Project.Target.0 - - Desktop - true - Desktop - Desktop - {120e6ad0-5207-4289-8a6a-7630e1616590} - 0 - 0 - 0 - - /home/deadvey/code/rust/happening - - - true - build - cargo - %{ActiveProject:ProjectDirectory} - /home/deadvey/code/rust/happening - ProjectExplorer.ProcessStep - - 1 - Build - Build - ProjectExplorer.BuildSteps.Build - - - 0 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - cargo build - WorkspaceProject.BuildConfiguration - 0 - 0 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - 0 - true - - - 2 - - false - -e cpu-cycles --call-graph dwarf,4096 -F 250 - cargo run - WorkspaceProject.RunConfiguration: - cargo run1 - false - - true - true - false - run - cargo - %{ActiveProject:ProjectDirectory} - - 1 - - true - cargo build - - - - build - - cargo - %{ActiveProject:ProjectDirectory} - - - - - - /home/deadvey/code/rust/happening/build - - 0 - Build - Build - ProjectExplorer.BuildSteps.Build - - - 0 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Default - WorkspaceProject.BuildConfiguration - 0 - 0 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - 0 - true - - - 2 - - false - -e cpu-cycles --call-graph dwarf,4096 -F 250 - cargo run - WorkspaceProject.RunConfiguration: - cargo run1 - false - - true - true - false - run - cargo - %{ActiveProject:ProjectDirectory} - - 1 - - 2 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - 0 - true - - - 2 - - false - -e cpu-cycles --call-graph dwarf,4096 -F 250 - cargo run - WorkspaceProject.RunConfiguration: - cargo run1 - false - - true - true - false - run - cargo - %{ActiveProject:ProjectDirectory} - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - Version - 22 - - diff --git a/Cargo.lock b/Cargo.lock index ba88abf..58803f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,65 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -35,6 +94,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -64,6 +129,29 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "env_filter" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -157,6 +245,8 @@ dependencies = [ name = "happening-server" version = "0.1.0" dependencies = [ + "env_logger", + "log", "serde", "tokio", "warp", @@ -283,12 +373,42 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jiff" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "libc" version = "0.2.184" @@ -340,6 +460,12 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + [[package]] name = "percent-encoding" version = "2.3.2" @@ -372,6 +498,21 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + [[package]] name = "proc-macro2" version = "1.0.106" @@ -390,6 +531,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + [[package]] name = "ryu" version = "1.0.23" @@ -584,6 +754,12 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index 94a3e47..898fe0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" edition = "2024" [dependencies] +env_logger = "0.11.10" +log = "0.4.29" serde = { version = "1.0.228", features = ["derive"] } tokio = { version = "1.51.0", features = ["rt-multi-thread","macros"] } warp = { version = "0.4.2", features = ["server"] } diff --git a/src/api.rs b/src/api.rs index 8336191..2eb75eb 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,40 +1,48 @@ -use warp::Filter; -use std::{ - thread, - sync::{Arc, Mutex}, -}; -use crate::config; use serde::{Deserialize, Serialize}; -use crate::mpsc::*; -use tokio::sync::RwLock; -use crate::api; +use warp::Filter; +use crate:: +{ + Arc, + Mutex, + config, + mpsc::Sender, + info, + warn, + debug, +}; #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct Data_to_send { +pub struct DataToSend { pub action_type: String, pub content: String, pub character: String, } -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct Data_to_receive { - pub response: String, -} -pub async fn api_process(data_to_send: Arc>, tx: Sender) +// Async function that runs the api server in the background. +// Waits for the client to load it, at which point it sends a 1 over +// tx to allow the program executor to move onto the next bit of code +pub async fn api_process(data_to_send: Arc>, tx: Sender) { + // This data must be passed through to the api route in order to be used let data_filter = warp::any().map(move || Arc::clone(&data_to_send)); let tx_filter = warp::any().map(move || tx.clone()); - println!("Running server"); + + debug!("Running server"); + + // The server route is loaded at address:port/happening let route = warp::path("happening") .and(warp::get()) .and(data_filter) .and(tx_filter) - .map(|state: Arc>, tx_handle: Sender| { - println!("GET: {:?}", state); + // Perform this code on a GET request + .map(|state: Arc>, tx_handle: Sender| { + info!("GET: {:?}", state); let reply = state.as_ref(); - tx_handle.send(1); - warp::reply::json(&reply) + let _ = tx_handle.send(1); + warp::reply::json(&reply) // Send the reply data (data_to_send formatted as JSON) }).boxed(); + + // Start the server warp::serve(route) .run(([127, 0, 0, 1],config::API_PORT)) .await; diff --git a/src/main.rs b/src/main.rs index afce756..45cf579 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,16 @@ use std:: { fs, - thread, collections::HashMap, sync::{Arc, Mutex, mpsc}, }; -use serde::{Deserialize, Serialize}; -use tokio::runtime::Runtime; -use tokio::task; -use warp::Filter; +use log:: +{ + info, + trace, + warn, + debug, +}; mod parsing; mod character; @@ -16,9 +18,11 @@ mod config; mod api; #[tokio::main] -async fn main() { +async fn main() +{ + env_logger::init(); let (tx,rx) = mpsc::channel(); - let mut data_to_send = Arc::new(Mutex::new(api::Data_to_send + let data_to_send = Arc::new(Mutex::new(api::DataToSend { action_type: "initialise".to_string(), content: "".to_string(), @@ -32,7 +36,7 @@ async fn main() { async move { api::api_process(data, tx_clone).await; }); - println!("and continue"); + debug!("and continue"); let mut characters = HashMap::::new(); let file_contents: String = fs::read_to_string("stories/story.ha").unwrap(); // Split the file contents into tokens @@ -43,7 +47,7 @@ async fn main() { let data_clone = Arc::clone(&data_to_send); match parsing::token_parse(&tokens, &mut characters, data_clone, &rx).await { - Ok(()) => println!("Program exited successfully"), - Err(error) => println!("{}", error), + Ok(()) => info!("Program exited successfully"), + Err(error) => eprintln!("{}", error), } } diff --git a/src/parsing.rs b/src/parsing.rs index 787fdc8..6aabbe6 100644 --- a/src/parsing.rs +++ b/src/parsing.rs @@ -1,19 +1,29 @@ use std::collections::HashMap; -use crate::character; -use crate::api; -use crate::mpsc::*; -use std::{thread}; -use std::sync::{Arc,Mutex}; use std::time::Duration; - +use std::thread; mod strings; +use crate:: +{ + // Internal code + character, + api, + + // Libraries + mpsc::Receiver, + Arc, + Mutex, + info, + warn, + debug, +}; + // Parse the tokens in a file // Returns success or an error string pub async fn token_parse( tokens: &Vec<&str>, mut characters: &mut HashMap::, - data_to_send: Arc>, + data_to_send: Arc>, rx: &Receiver, ) -> Result<(),String> { @@ -21,44 +31,41 @@ pub async fn token_parse( // Run an infinite loop loop { - match rx.try_recv() + // If the client hasn't responded then continue (after a short pause) + if rx.try_recv().is_err() { - Ok(_) => - { - match tokens.get(index) { - Some(token) => { - // The instructions are related to characters - if token.chars().next().unwrap() == '@' - { - let character_name: String = token.chars().skip(1).collect(); - // If the character doesn't exist, then create it - if ! characters.contains_key(&character_name) - { - let new_character = character::Character::new(character_name.clone()); - characters.insert(character_name.clone(),new_character); - } - println!("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), - } - } - // Miscelleneous instructions - if token.to_lowercase() == "end" - { - return Ok(()) // quit - } - }, - None => return Err(String::from("File reached termination point")), - } - index += 1; - }, - Err(_) => thread::sleep(Duration::from_millis(4000)), + thread::sleep(Duration::from_millis(300)); + continue } + // Get the next token + let token = tokens + .get(index) + .ok_or_else(|| "File reached termination point".to_string())?; + + // The instructions are related to characters + if token.starts_with('@') + { + let character_name: String = token.chars().skip(1).collect(); + // If the character doesn't exist, then create it + if ! characters.contains_key(&character_name) + { + let new_character = character::Character::new(character_name.clone()); + characters.insert(character_name.clone(),new_character); + } + println!("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), + } + } + // Miscelleneous instructions + if token.to_lowercase() == "end" + { + return Ok(()) // quit + } + index += 1; } } // Parsing character related instructions @@ -68,7 +75,7 @@ async fn character_parse tokens: &Vec<&str>, character_name: String, characters: &mut HashMap::, - data_to_send: &Arc>, + data_to_send: &Arc>, rx: &Receiver, ) -> Result { @@ -76,35 +83,32 @@ async fn character_parse loop { // Ensure the index is valid (the index is not beyond the vector) - let _ = match tokens.get(sum_index) + let token = tokens + .get(sum_index) + .ok_or_else(|| "File reached termination point".to_string())?; + match token.to_lowercase().as_str() { - Some(token) => { - match token.to_lowercase().as_str() + // The character is saying something, so grab the text and pass it + // to the client + "says" => + { + match strings::extract_quoted(&tokens[sum_index+1..]) // TODO increment to after the string { - // The character is saying something, so grab the text and pass it - // to the client - "says" => + Some(output_string) => { - match strings::extract_quoted(&tokens[sum_index+1..]) - { - Some(output_string) => - { - println!("{}", 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")), - } + 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(); }, - // Catch all condition, if the instruction is unrecognised as a - // character command - _ => return Err(String::from("Invalid command")), + None => return Err(String::from("Unable to read string")), } }, - None => return Err(String::from("File reached termination point")) - }; + // Catch all condition, if the instruction is unrecognised as a + // character command + _ => return Err(String::from(format!("Invalid command: {}", token))), + } sum_index += 1; } } diff --git a/src/.api.rs.swp b/src/parsing/.strings.rs.swp similarity index 88% rename from src/.api.rs.swp rename to src/parsing/.strings.rs.swp index 9dc8f1caa4e23968f1efd804fadfa4769d622259..9b28f4efbdea44d23f98abe8b153b436e97c60f4 100644 GIT binary patch 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^ literal 12288 zcmYc?2=nw+u+%eRU|?VnU|>-0d!Oms6~eH`oPi-FH8G_uwGt$Q7w2T=l~(8$B;!@Y zz`#%kHBdh}KP6SasI<65KO?cAAT=*DFI~U5C|N(TAXBfXn2<4}@}nUz8Umz-Kxs*u zt_3fHv5}zxNUO4vqJpqcD2O?VM?+vV1V%$(Gz3ONU^E0qLtr!nMnhmU1V%^*loT*B z)H5(JFhTvR38fj)Xef7-8V!Nb5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c zf+3KY!oXm|&A{-38#4b7>;J#wXJB~D&%khtpMl{hKLf)deg=m1{0t0T{0t0b{0t1S z{0t1f{0s~}{0s~-{0t0C{0s~)_!t;2@i8#$;$vXg!NtH?csY2CUIa!LcaW#<#R2wZg_Fu_Q6RBtITxlbxN80^DvZ zh2Ye@l++@dQVY8pg=$a$B<7`PlvKp0W#*Km7J*!<2NFpEnSdq+34-+05)Dv*fL#s> z2nAaOh)h9ZNrr|Jd||VaCIctJ{XwO9pw-R_;1DcQ0=XV!0^DY}DT#TN8k%5#<>r^A zD%8{{lvL;?=j7+5YG}fAA-N8ZKF6YDD=UajHLwn7h=7c#W+*64Qb;VW%u7~C%Tq`! z$c!&2%1=%$F4jO+ia$`1LsOH1p_YLYWN1-paY24wajKOCierJIa3>j`>C@oG^NG?h&Nwu;{ zEXcG5^GouxGxM#iKtXI}6;$q%pPUVmfGW%_C{DJr(t?N;rxvB8T3J Option { +pub fn extract_quoted(parts: &[&str]) -> Option { // TODO also return a number to increment by let mut vec_string = Vec::new(); for part in parts { - println!("{}",part); if part.chars().next_back().unwrap() == '"' { vec_string.push(*part); diff --git a/stories/story.ha b/stories/story.ha index dce32b6..d9f5a16 100644 --- a/stories/story.ha +++ b/stories/story.ha @@ -1,2 +1 @@ -@tim says "this text is outputted" -END +@tim says "hello to all the world"