futures_jsonrpc/
handler.rs

1use crate::futures::prelude::*;
2use crate::{ErrorVariant, JrpcMethodTrait, JrpcRequest, JrpcResponse};
3use std::collections::HashMap;
4use std::sync::{Arc, RwLock};
5
6pub struct JrpcHandler<'a> {
7    hm_methods: Arc<RwLock<HashMap<String, Box<dyn JrpcMethodTrait<'a> + 'a>>>>,
8}
9
10impl<'a> JrpcHandler<'a> {
11    pub fn new() -> Result<Self, ErrorVariant> {
12        let hm_methods = Arc::new(RwLock::new(HashMap::new()));
13        let handler = JrpcHandler { hm_methods };
14        Ok(handler)
15    }
16
17    pub fn register_method<T: ToString, F: JrpcMethodTrait<'a> + 'a>(
18        &self,
19        signature: T,
20        jrpc_method: F,
21    ) -> Result<&Self, ErrorVariant> {
22        let signature = signature.to_string();
23        let jrpc_method = Box::new(jrpc_method);
24        let log_message = format!("Signature {} registered as method", &signature);
25
26        {
27            self.hm_methods
28                .try_write()
29                .map_err(|_| ErrorVariant::RwLockPoisoned)
30                .and_then(|mut hm| {
31                    hm.insert(signature, jrpc_method);
32                    Ok(())
33                })?;
34        }
35
36        trace!("{}", log_message);
37        Ok(self)
38    }
39
40    pub fn handle_message<T: ToString>(
41        &self,
42        message: T,
43    ) -> Result<Box<'a + Future<Item = Option<JrpcResponse>, Error = ErrorVariant>>, ErrorVariant>
44    {
45        let message = message.to_string();
46        let log_message = format!("Message {}", &message);
47        let request = JrpcRequest::parse(message)?;
48        let log_message = format!("{} generated response {:?}", &log_message, &request);
49
50        let future = {
51            self.hm_methods
52                .try_read()
53                .map_err(|_| ErrorVariant::RwLockPoisoned)
54                .and_then(|hm| {
55                    hm.get(request.get_method())
56                        .map(|method| Ok(method))
57                        .unwrap_or(Err(ErrorVariant::MethodSignatureNotFound(
58                            request.get_method().clone(),
59                        )))
60                        .and_then(|method| method.generate_future(request))
61                })?
62        };
63
64        trace!("{}", log_message);
65        Ok(future)
66    }
67}