rpc_api/rpc/
handlers.rs

1use std::collections::HashMap;
2use std::fmt::Debug;
3use std::sync::Arc;
4use std::task::Context;
5
6use serde::de::DeserializeOwned;
7use serde::Serialize;
8
9use crate::rpc::{conversions, get_handler_key, ReqResBound};
10use crate::rpc::conversions::rpc_error;
11use crate::rpc::http::{HttpHandler, HttpRequest, HttpResponse};
12
13pub trait Request<Req> {}
14
15pub struct Handlers<Ctx> {
16    handlers: HashMap<String, Box<dyn Fn(&str, Ctx) -> String + Send + Sync>>,
17}
18
19
20impl<Ctx: 'static> Handlers<Ctx> {
21    pub fn new() -> Handlers<Ctx> {
22        Handlers { handlers: HashMap::new() }
23    }
24
25    pub fn new_http_handler(self, context_generator: fn(&HttpRequest) -> Ctx) -> HttpHandler {
26        Arc::new(move |req: HttpRequest| -> HttpResponse {
27            HttpResponse::new(self.dispatch(&req.content, context_generator(&req)))
28        })
29    }
30
31    pub fn register<Req: ReqResBound, Res: ReqResBound>(&mut self, callback: impl Fn(Req, Ctx) -> Result<Res, String> + Send + Sync + 'static)
32        where Req: Request<Res>
33    {
34        let handler_key = get_handler_key::<Req>();
35        println!("registering=`{handler_key}`");
36        self.handlers.insert(handler_key, Box::new(move |payload, ctx| {
37            let req = conversions::rpc_req_from_str(payload);
38            if let Err(msg) = req { return msg; }
39            let res = callback(req.unwrap(), ctx);
40            match res {
41                Ok(ok) => { conversions::rpc_res_to_str(&ok) }
42                Err(msg) => { rpc_error(&msg) }
43            }
44        }));
45    }
46
47    pub fn dispatch(&self, request_payload: &str, ctx: Ctx) -> String {
48        let payload = Payload::from(request_payload);
49        match payload {
50            Err(msg) => { rpc_error(&msg) }
51            Ok(payload) => {
52                let x = self.handlers.get(payload.handler_key);
53                match x {
54                    None => {
55                        let msg1 = format!("dispatch(...) handler not found `{}`", payload.handler_key);
56                        rpc_error(&msg1)
57                    }
58                    Some(fun) => { fun(payload.json, ctx) }
59                }
60            }
61        }
62    }
63}
64
65
66pub struct Payload<'a> {
67    pub handler_key: &'a str,
68    pub json: &'a str,
69}
70
71impl<'a> Payload<'a> {
72    pub fn from(payload: &str) -> Result<Payload, String> {
73        let mut s = payload.splitn(2, "\n");
74        let h = s.next().ok_or("Payload split 1")?;
75        let j = s.next().ok_or("Payload split 2")?;
76        Ok(Payload {
77            handler_key: h,
78            json: j,
79        })
80    }
81
82    pub fn to_string(&self) -> String {
83        self.handler_key.to_owned() + "\n" + &*self.json
84    }
85}
86