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