1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::app::AppOptions;
use crate::context::PicoContext;
use crate::rules::PicoRules;
use crate::runtime::PicoRuntime;
use std::convert::Infallible;
use std::result::Result;
use std::sync::Arc;
use tokio::sync::RwLock;

use jsonpath_lib as jsonpath;

use warp::{reply::json, Filter, Rejection, Reply};

pub async fn serve(pico: Arc<RwLock<PicoRules>>, app: AppOptions) {
    info!("Serve {:?}", app);

    let submit = warp::path("submit");
    let submit_route = submit
        .and(warp::post())
        .and(warp::body::json())
        .and(with_pico(pico.clone()))
        .and_then(submit_handler);

    let routes = submit_route.with(warp::cors().allow_any_origin());

    let port = app.port;

    warp::serve(routes).run(([127, 0, 0, 1], 8000)).await
}

#[derive(Serialize, Deserialize, Debug)]
pub struct SubmitResponse {
    output: String,
}

pub async fn submit_handler(
    body: serde_json::Value,
    pico: Arc<RwLock<PicoRules>>,
) -> Result<impl Reply, Rejection> {
    let re = pico.read().await;

    let mut runtime = PicoRuntime::new(&re).initialise();

    trace!("InVars... {:?}", body);
    //let mut ctx = PicoContext::new().set_json(body);
    let mut ctx = runtime.make_ctx().set_json(body);
    trace!("INITIAL CTX = {:?}", ctx);

    re.run_with_context(&mut runtime, &mut ctx);
    info!("\n FINAL CTX {:?}", ctx);
    info!("\n FINAL runtime globals {:?}", runtime.globals);

    Ok(json(ctx.get_final_ctx()))
}

pub fn with_pico(
    pico: Arc<RwLock<PicoRules>>,
) -> impl Filter<Extract = (Arc<RwLock<PicoRules>>,), Error = Infallible> + Clone {
    warp::any().map(move || pico.clone())
}