endpoint_libs/libs/
handler.rs1use async_trait::async_trait;
2use eyre::Result;
3use serde_json::Value;
4
5use super::{
6 error_code::ErrorCode,
7 toolbox::{ArcToolbox, RequestContext, Toolbox},
8 ws::{request_error_to_resp, WsRequest},
9};
10
11#[allow(type_alias_bounds)]
12pub type Response<T: WsRequest> = Result<T::Response>;
13#[async_trait(?Send)]
14pub trait RequestHandler: Send + Sync {
15 type Request: WsRequest + 'static;
16
17 async fn handle(&self, ctx: RequestContext, req: Self::Request) -> Response<Self::Request>;
18}
19
20#[doc(hidden)]
21#[async_trait(?Send)]
22pub trait RequestHandlerErased: Send + Sync {
23 async fn handle(&self, toolbox: &ArcToolbox, ctx: RequestContext, req: Value);
24}
25
26#[async_trait(?Send)]
27impl<T: RequestHandler> RequestHandlerErased for T {
28 async fn handle(&self, toolbox: &ArcToolbox, ctx: RequestContext, req: Value) {
29 let buf = serde_json::to_string(&req).unwrap();
31 let data: T::Request = match serde_json::from_value(req) {
32 Ok(data) => data,
33 Err(err) => {
34 let jd = &mut serde_json::Deserializer::from_str(&buf);
35 let data: Result<T::Request, _> = serde_path_to_error::deserialize(jd);
36 let path = data.err().map(|err| err.path().to_string());
37 toolbox.send(
38 ctx.connection_id,
39 request_error_to_resp(
40 &ctx,
41 ErrorCode::new(100400), if let Some(path) = path {
43 format!("{path}: {err}")
44 } else {
45 format!("{err}")
46 },
47 ),
48 );
49 return;
50 }
51 };
52
53 let fut = RequestHandler::handle(self, ctx, data);
54
55 let resp = fut.await;
56 if let Some(resp) = Toolbox::encode_ws_response(ctx, resp) {
57 toolbox.send(ctx.connection_id, resp);
58 }
59 }
60}