Skip to main content

elite_rpc/
lib.rs

1//! Type Safe JSON RPC like client with different
2//! transport layer.
3//!
4//! Author: Vincenzo Palazzo <vincenzopalazzo@member.fsf.org>
5use std::marker::PhantomData;
6
7pub use serde_json as json;
8
9pub mod protocol;
10pub mod transport;
11
12use crate::protocol::Protocol;
13use crate::transport::Transport;
14use crate::transport::TransportMethod;
15
16pub struct EliteRPC<T: Transport<P>, P: Protocol> {
17    transport: T,
18    phantom: PhantomData<P>,
19}
20
21impl<P: Protocol, T: Transport<P>> EliteRPC<T, P> {
22    pub fn new(info: &str) -> anyhow::Result<Self> {
23        let protocol = P::new()?;
24        let transport = T::new(info, protocol)?;
25        Ok(Self {
26            transport,
27            phantom: PhantomData {},
28        })
29    }
30
31    pub fn call(
32        &self,
33        method: TransportMethod,
34        request: &P::InnerType,
35    ) -> anyhow::Result<P::InnerType> {
36        self.transport.call(method, request)
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use crate::protocol::Protocol;
43    use crate::transport::{Transport, TransportMethod};
44    use crate::EliteRPC;
45
46    pub struct MockTransport;
47    #[derive(Clone)]
48    pub struct MockProtocol;
49
50    impl Transport<MockProtocol> for MockTransport {
51        fn new(_: &str, _: MockProtocol) -> anyhow::Result<Self>
52        where
53            Self: Sized,
54        {
55            Ok(Self)
56        }
57
58        fn call(
59            &self,
60            _: TransportMethod,
61            _: &<MockProtocol as Protocol>::InnerType,
62        ) -> anyhow::Result<<MockProtocol as Protocol>::InnerType> {
63            Ok(())
64        }
65    }
66
67    impl Protocol for MockProtocol {
68        type InnerType = ();
69
70        fn from_request(
71            &self,
72            _: &[u8],
73            _: Option<crate::protocol::Encoding>,
74        ) -> anyhow::Result<Self::InnerType> {
75            Ok(())
76        }
77
78        fn new() -> anyhow::Result<Self>
79        where
80            Self: Sized,
81        {
82            Ok(MockProtocol)
83        }
84
85        fn to_request(
86            &self,
87            _: &str,
88            _: &Self::InnerType,
89        ) -> anyhow::Result<(String, Self::InnerType)> {
90            Ok((String::new(), ()))
91        }
92    }
93
94    #[test]
95    pub fn test_init_example() -> anyhow::Result<()> {
96        let rpc = EliteRPC::<MockTransport, MockProtocol>::new("")?;
97        let response = rpc.call(TransportMethod::Get("foo".to_owned()), &())?;
98        assert_eq!(response, ());
99        Ok(())
100    }
101}