138 lines
3.5 KiB
Rust
138 lines
3.5 KiB
Rust
use warp::Filter;
|
|
use crate::
|
|
{
|
|
// internal code
|
|
character,
|
|
UnwrapOrExit,
|
|
// libraries
|
|
json,
|
|
HashMap,
|
|
Arc,
|
|
Mutex,
|
|
VecDeque,
|
|
config,
|
|
mpsc::Sender,
|
|
info,
|
|
debug,
|
|
warn,
|
|
Serialize,
|
|
Deserialize,
|
|
};
|
|
|
|
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
|
|
pub struct DataToSend {
|
|
pub action_type: String,
|
|
pub content: String,
|
|
pub character: String,
|
|
pub choices: Vec<String>,
|
|
}
|
|
|
|
// 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
|
|
(
|
|
happening_queue: Arc<Mutex<VecDeque<DataToSend>>>,
|
|
characters: Arc<Mutex<HashMap::<String,character::Character>>>,
|
|
tx: Sender<(usize, String)>,
|
|
)
|
|
{
|
|
// This data must be passed through to the api route in order to be used
|
|
let happening_queue_filter = warp::any().map(move || Arc::clone(&happening_queue));
|
|
let characters_filter = warp::any().map(move || Arc::clone(&characters));
|
|
let tx_filter1 = warp::any().map(move || tx.clone());
|
|
let tx_filter2 = tx_filter1.clone();
|
|
|
|
info!("Running server");
|
|
|
|
// The server route is loaded at address:port/happening
|
|
let main = warp::path("happening")
|
|
.and(warp::get())
|
|
.and(happening_queue_filter)
|
|
// Perform this code on a GET request
|
|
.map(|queue: Arc<Mutex<VecDeque<DataToSend>>>|
|
|
{
|
|
//debug!("GET: {state:?}");
|
|
let mut queue = queue.lock().unwrap_or_exit("Queue Mutex was poisoned", 2);
|
|
let reply = queue.pop_front().unwrap_or_default();
|
|
drop(queue);
|
|
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 reply =
|
|
{
|
|
let characters = match characters.lock()
|
|
{
|
|
Ok(data) => data,
|
|
Err(poisoned) =>
|
|
{
|
|
warn!("Character Mutex is poisoned");
|
|
poisoned.into_inner()
|
|
},
|
|
};
|
|
characters.get(&name).cloned()
|
|
};
|
|
|
|
let Some(reply) = reply else
|
|
{
|
|
warn!("Client requested character that does not exist");
|
|
return warp::reply::json(&json!({"reply": "invalid character"}));
|
|
};
|
|
debug!("GET: name: {name}");
|
|
warp::reply::json(&reply)
|
|
}).boxed();
|
|
let choice = warp::path("choice")
|
|
.and(warp::post())
|
|
.and(warp::body::json())
|
|
.and(tx_filter1)
|
|
.map(|index: usize, tx_handle: Sender<(usize,String)>| {
|
|
debug!("Choice: {index}");
|
|
let _ = tx_handle.send((index,String::new()));
|
|
let reply = "ack";
|
|
warp::reply::json(&reply)
|
|
}).boxed();
|
|
let input = warp::path("input")
|
|
.and(warp::post())
|
|
.and(warp::body::json())
|
|
.and(tx_filter2)
|
|
.map(|input: String, tx_handle: Sender<(usize, String)>|
|
|
{
|
|
let _ = tx_handle.send((0,input));
|
|
let reply = "ack";
|
|
warp::reply::json(&reply)
|
|
}).boxed();
|
|
|
|
let routes = main.or(characters).or(choice).or(input);
|
|
// Start the server
|
|
warp::serve(routes)
|
|
.run(([127, 0, 0, 1],config::API_PORT))
|
|
.await;
|
|
}
|
|
|
|
// On fail, quit safely
|
|
// If successful, return nothing
|
|
pub fn modify_data // TODO rename
|
|
(
|
|
happening_queue: &Arc<Mutex<VecDeque<DataToSend>>>,
|
|
action_type: String,
|
|
content: String,
|
|
character: String,
|
|
choices: Vec<String>,
|
|
)
|
|
{
|
|
let mut queue = happening_queue.lock().unwrap_or_exit("Data to send Mutex was poisoned",2);
|
|
let new_data = DataToSend {
|
|
action_type,
|
|
content,
|
|
character,
|
|
choices,
|
|
};
|
|
queue.push_back(new_data);
|
|
drop(queue);
|
|
}
|