Added a character route for requesting character data from the server
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
,deadvey,linux-pc,07.04.2026 00:08,file:///home/deadvey/.config/libreoffice/4;
|
||||
,deadvey,linux-pc,30.04.2026 12:49,file:///home/deadvey/.config/libreoffice/4;
|
||||
Generated
+1
@@ -248,6 +248,7 @@ dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"warp",
|
||||
]
|
||||
|
||||
@@ -7,5 +7,6 @@ edition = "2024"
|
||||
env_logger = "0.11.10"
|
||||
log = "0.4.29"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
serde_json = "1.0.149"
|
||||
tokio = { version = "1.51.0", features = ["rt-multi-thread","macros"] }
|
||||
warp = { version = "0.4.2", features = ["server"] }
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
+30
-7
@@ -1,14 +1,18 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use warp::Filter;
|
||||
use crate::
|
||||
{
|
||||
// internal code
|
||||
character,
|
||||
// libraries
|
||||
HashMap,
|
||||
Arc,
|
||||
Mutex,
|
||||
config,
|
||||
mpsc::Sender,
|
||||
info,
|
||||
warn,
|
||||
debug,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
@@ -21,29 +25,48 @@ pub struct DataToSend {
|
||||
// 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<Mutex<DataToSend>>, tx: Sender<u8>)
|
||||
pub async fn api_process
|
||||
(
|
||||
data_to_send: Arc<Mutex<DataToSend>>,
|
||||
characters: Arc<Mutex<HashMap::<String,character::Character>>>,
|
||||
tx: Sender<u8>,
|
||||
)
|
||||
{
|
||||
// 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 characters_filter = warp::any().map(move || Arc::clone(&characters));
|
||||
let tx_filter = warp::any().map(move || tx.clone());
|
||||
|
||||
debug!("Running server");
|
||||
info!("Running server");
|
||||
|
||||
// The server route is loaded at address:port/happening
|
||||
let route = warp::path("happening")
|
||||
let main = warp::path("happening")
|
||||
.and(warp::get())
|
||||
.and(data_filter)
|
||||
.and(tx_filter)
|
||||
// Perform this code on a GET request
|
||||
.map(|state: Arc<Mutex<DataToSend>>, tx_handle: Sender<u8>| {
|
||||
.map(|state: Arc<Mutex<DataToSend>>, tx_handle: Sender<u8>|
|
||||
{
|
||||
info!("GET: {:?}", state);
|
||||
let reply = state.as_ref();
|
||||
let _ = tx_handle.send(1);
|
||||
warp::reply::json(&reply) // Send the reply data (data_to_send formatted as JSON)
|
||||
}).boxed();
|
||||
let characters = warp::path("character")
|
||||
.and(warp::get())
|
||||
.and(warp::path::param::<String>())
|
||||
.and(characters_filter)
|
||||
.map(|name: String, characters: Arc<Mutex<HashMap<String, character::Character>>>|
|
||||
{
|
||||
let map = characters.lock().unwrap(); // TODO remove unwrap
|
||||
let reply = map.get(&name).unwrap();
|
||||
debug!("GET: name: {}, data: {:?}", name, reply);
|
||||
warp::reply::json(&reply)
|
||||
}).boxed();
|
||||
|
||||
let routes = main.or(characters);
|
||||
// Start the server
|
||||
warp::serve(route)
|
||||
warp::serve(routes)
|
||||
.run(([127, 0, 0, 1],config::API_PORT))
|
||||
.await;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,33 @@
|
||||
use crate::{
|
||||
HashMap,
|
||||
fs,
|
||||
debug,
|
||||
Deserialize,
|
||||
Serialize,
|
||||
Mutex,
|
||||
Arc,
|
||||
};
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Character
|
||||
{
|
||||
name: String,
|
||||
gender: String,
|
||||
eye_color: String,
|
||||
pronoun_subject: String,
|
||||
pronoun_object: String,
|
||||
pronoun_deppos: String,
|
||||
pronoun_indpos: String,
|
||||
pronoun_reflex: String,
|
||||
animation: String,
|
||||
head: String,
|
||||
hair: String,
|
||||
torso: String,
|
||||
arm: String,
|
||||
leg: String,
|
||||
hair_color: String,
|
||||
top_clothing: String,
|
||||
bottom_clothing: String,
|
||||
shoes: String,
|
||||
}
|
||||
impl Character
|
||||
{
|
||||
@@ -9,6 +36,38 @@ impl Character
|
||||
Character
|
||||
{
|
||||
name: new_name,
|
||||
gender: "".to_string(),
|
||||
eye_color: "".to_string(),
|
||||
pronoun_subject: "".to_string(),
|
||||
pronoun_object: "".to_string(),
|
||||
pronoun_deppos: "".to_string(),
|
||||
pronoun_indpos: "".to_string(),
|
||||
pronoun_reflex: "".to_string(),
|
||||
animation: "".to_string(),
|
||||
head: "".to_string(),
|
||||
hair: "".to_string(),
|
||||
torso: "".to_string(),
|
||||
arm: "".to_string(),
|
||||
leg: "".to_string(),
|
||||
hair_color: "".to_string(),
|
||||
top_clothing: "".to_string(),
|
||||
bottom_clothing: "".to_string(),
|
||||
shoes: "".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn character_parse()
|
||||
-> Result<Arc<Mutex<HashMap<String, Character>>>,String>
|
||||
{
|
||||
// Get the JSON file to a string
|
||||
let file_contents: String = fs::read_to_string("stories/characters.json")
|
||||
.unwrap_or_else(|err| { return err.to_string() });
|
||||
|
||||
// Serialise this to a HashMap
|
||||
let characters: HashMap<String, Character> =
|
||||
serde_json::from_str(&file_contents)
|
||||
.expect("JSON was not well-formatted");
|
||||
debug!("{:?}",characters);
|
||||
Ok(Arc::new(Mutex::new(characters)))
|
||||
}
|
||||
|
||||
+21
-5
@@ -10,6 +10,8 @@ use log::
|
||||
warn,
|
||||
debug,
|
||||
};
|
||||
use serde_json::from_str;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod parsing;
|
||||
mod character;
|
||||
@@ -30,24 +32,33 @@ async fn main()
|
||||
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<Mutex<HashMap::<String, character::Character>>> = 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, tx_clone).await;
|
||||
api::api_process(data_clone1, characters_clone1, tx_clone).await;
|
||||
});
|
||||
|
||||
|
||||
// setup the parsing stuff //
|
||||
// Setup the characters hashmap which will store each character in it as a Character struct
|
||||
let mut characters = HashMap::<String, character::Character>::new();
|
||||
|
||||
// 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|
|
||||
@@ -58,10 +69,15 @@ async fn main()
|
||||
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, &mut characters, data_clone2, &rx).await
|
||||
match parsing::token_parse(&tokens, characters_clone2, data_clone2, &rx).await
|
||||
{
|
||||
// Exit with error or success
|
||||
Ok(()) =>
|
||||
|
||||
+3
-10
@@ -11,7 +11,6 @@ use crate::
|
||||
Arc,
|
||||
Mutex,
|
||||
info,
|
||||
warn,
|
||||
debug,
|
||||
};
|
||||
|
||||
@@ -20,7 +19,7 @@ use crate::
|
||||
// Returns success or an error string
|
||||
pub async fn token_parse(
|
||||
tokens: &Vec<&str>,
|
||||
mut characters: &mut HashMap::<String, character::Character>,
|
||||
mut characters: Arc<Mutex<HashMap::<String, character::Character>>>,
|
||||
data_to_send: Arc<Mutex<api::DataToSend>>,
|
||||
rx: &Receiver<u8>,
|
||||
) -> Result<(),String>
|
||||
@@ -43,15 +42,9 @@ pub async fn token_parse(
|
||||
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);
|
||||
}
|
||||
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
|
||||
index += match character_parse(index+1, &tokens, character_name, &characters, &data_to_send, &rx).await
|
||||
{
|
||||
Ok(increment) => increment,
|
||||
Err(error) => return Err(error),
|
||||
@@ -73,7 +66,7 @@ async fn character_parse
|
||||
index: usize,
|
||||
tokens: &Vec<&str>,
|
||||
character_name: String,
|
||||
characters: &mut HashMap::<String, character::Character>,
|
||||
characters: &Arc<Mutex<HashMap::<String, character::Character>>>,
|
||||
data_to_send: &Arc<Mutex<api::DataToSend>>,
|
||||
rx: &Receiver<u8>,
|
||||
) -> Result<usize,String>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"tim": {
|
||||
"name": "Timothy Sharpshooter",
|
||||
"gender": "",
|
||||
"skin_color": "",
|
||||
"eye_color": "",
|
||||
"pronoun_subject": "",
|
||||
"pronoun_object": "",
|
||||
"pronoun_deppos": "",
|
||||
"pronoun_indpos": "",
|
||||
"pronoun_reflex": "",
|
||||
"animation": "",
|
||||
"head": "",
|
||||
"hair": "",
|
||||
"torso": "",
|
||||
"arm": "",
|
||||
"leg": "",
|
||||
"hair_color": "",
|
||||
"top_clothing": "",
|
||||
"bottom_clothing": "",
|
||||
"shoes": ""
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user