casper_json_rpc/
request_handlers.rs1use std::{collections::HashMap, future::Future, pin::Pin, sync::Arc};
2
3use futures::FutureExt;
4use serde::Serialize;
5use serde_json::Value;
6use tracing::{debug, error};
7
8use crate::{
9 error::{Error, ReservedErrorCode},
10 request::{Params, Request},
11 response::Response,
12};
13
14type HandleRequestFuture = Pin<Box<dyn Future<Output = Result<Value, Error>> + Send>>;
16type RequestHandler = Arc<dyn Fn(Option<Params>) -> HandleRequestFuture + Send + Sync>;
18
19#[derive(Clone)]
24pub struct RequestHandlers(Arc<HashMap<&'static str, RequestHandler>>);
25
26impl RequestHandlers {
27 pub(crate) async fn handle_request(&self, request: Request) -> Response {
36 let handler = match self.0.get(request.method.as_str()) {
37 Some(handler) => Arc::clone(handler),
38 None => {
39 debug!(requested_method = %request.method.as_str(), "failed to get handler");
40 let error = Error::new(
41 ReservedErrorCode::MethodNotFound,
42 format!(
43 "'{}' is not a supported json-rpc method on this server",
44 request.method.as_str()
45 ),
46 );
47 return Response::new_failure(request.id, error);
48 }
49 };
50
51 match handler(request.params).await {
52 Ok(result) => Response::new_success(request.id, result),
53 Err(error) => Response::new_failure(request.id, error),
54 }
55 }
56}
57
58#[derive(Default)]
63pub struct RequestHandlersBuilder(HashMap<&'static str, RequestHandler>);
64
65impl RequestHandlersBuilder {
66 pub fn new() -> Self {
68 Self::default()
69 }
70
71 pub fn register_handler<Func, Fut, T>(&mut self, method: &'static str, handler: Arc<Func>)
80 where
81 Func: Fn(Option<Params>) -> Fut + Send + Sync + 'static,
82 Fut: Future<Output = Result<T, Error>> + Send,
83 T: Serialize + 'static,
84 {
85 let handler = Arc::clone(&handler);
86 let wrapped_handler = move |maybe_params| {
90 let handler = Arc::clone(&handler);
91 async move {
92 let success = Arc::clone(&handler)(maybe_params).await?;
93 serde_json::to_value(success).map_err(|error| {
94 error!(%error, "failed to encode json-rpc response value");
95 Error::new(
96 ReservedErrorCode::InternalError,
97 format!("failed to encode json-rpc response value: {}", error),
98 )
99 })
100 }
101 .boxed()
102 };
103 if self.0.insert(method, Arc::new(wrapped_handler)).is_some() {
104 error!(
105 method,
106 "already registered a handler for this json-rpc request method"
107 );
108 }
109 }
110
111 pub fn build(self) -> RequestHandlers {
113 RequestHandlers(Arc::new(self.0))
114 }
115}