use std:: { fs, collections::HashMap, sync::{Arc, Mutex, mpsc}, }; use log:: { info, warn, debug, }; use serde_json::from_str; use serde::{Deserialize, Serialize}; mod parsing; mod character; mod config; 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: "begin".to_string(), content: "".to_string(), character: "".to_string(), })); // Setup the characters hashmap which will store each character in it as a Character struct let mut characters: Arc>> = Default::default(); match character::character_parse().await { Ok(result) => characters = result, //let mut characters = character, Err(error) => { eprintln!("{}",error); std::process::exit(3); }, }; // setup the api stuff // // Make clones of the data Arc for the two processes let data_clone1 = Arc::clone(&data_to_send); let characters_clone1 = Arc::clone(&characters); let tx_clone = tx.clone(); // Spawn a thread for warp api server tokio::spawn( async move { api::api_process(data_clone1, characters_clone1, tx_clone).await; }); // setup the parsing stuff // // 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(); if ! tokens.contains(&"END") { warn!("No END statement, story may exit unexpectedly"); } let data_clone2 = Arc::clone(&data_to_send); let characters_clone2 = Arc::clone(&characters); // Run the parsing process match parsing::token_parse(&tokens, characters_clone2, data_clone2, &rx).await { // 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); }, } }