graphwalker_restful/
rest.rs1use std::sync::mpsc;
2
3use axum::extract::{Path, State};
4use axum::http::StatusCode;
5use axum::response::Json;
6use serde_json::{json, Value};
7use tokio::sync::oneshot;
8
9use crate::actor::Command;
10
11#[derive(Clone)]
12pub struct RestState {
13 pub machine_tx: mpsc::Sender<Command>,
14 pub default_seed: Option<u64>,
15}
16
17async fn send_command(
18 tx: &mpsc::Sender<Command>,
19 build: impl FnOnce(oneshot::Sender<Result<Value, String>>) -> Command,
20) -> (StatusCode, Json<Value>) {
21 let (reply_tx, reply_rx) = oneshot::channel();
22 if tx.send(build(reply_tx)).is_err() {
23 return (
24 StatusCode::INTERNAL_SERVER_ERROR,
25 Json(json!({"result": "nok", "error": "Machine thread unavailable"})),
26 );
27 }
28 match reply_rx.await {
29 Ok(Ok(val)) => (StatusCode::OK, Json(val)),
30 Ok(Err(msg)) => (StatusCode::OK, Json(json!({"result": "nok", "error": msg}))),
31 Err(_) => (
32 StatusCode::INTERNAL_SERVER_ERROR,
33 Json(json!({"result": "nok", "error": "Machine thread dropped"})),
34 ),
35 }
36}
37
38pub async fn load(State(state): State<RestState>, body: String) -> (StatusCode, Json<Value>) {
39 send_command(&state.machine_tx, |reply| Command::Load {
40 json_body: body,
41 seed: state.default_seed,
42 global_data: None,
43 reply,
44 })
45 .await
46}
47
48pub async fn has_next(State(state): State<RestState>) -> (StatusCode, Json<Value>) {
49 send_command(&state.machine_tx, |reply| Command::HasNext { reply }).await
50}
51
52pub async fn get_next(State(state): State<RestState>) -> (StatusCode, Json<Value>) {
53 send_command(&state.machine_tx, |reply| Command::GetNext {
54 verbose: false,
55 reply,
56 })
57 .await
58}
59
60pub async fn get_data(State(state): State<RestState>) -> (StatusCode, Json<Value>) {
61 send_command(&state.machine_tx, |reply| Command::GetData { reply }).await
62}
63
64pub async fn set_data(
65 State(state): State<RestState>,
66 Path(script): Path<String>,
67) -> (StatusCode, Json<Value>) {
68 send_command(&state.machine_tx, |reply| Command::SetData { script, reply }).await
69}
70
71pub async fn restart(State(state): State<RestState>) -> (StatusCode, Json<Value>) {
72 send_command(&state.machine_tx, |reply| Command::Restart { reply }).await
73}
74
75pub async fn get_statistics(State(state): State<RestState>) -> (StatusCode, Json<Value>) {
76 send_command(&state.machine_tx, |reply| Command::GetStatistics { reply }).await
77}