use std::marker::PhantomData;
pub use serde_json as json;
pub mod protocol;
pub mod transport;
use crate::protocol::Protocol;
use crate::transport::Transport;
use crate::transport::TransportMethod;
pub struct EliteRPC<T: Transport<P>, P: Protocol> {
transport: T,
phantom: PhantomData<P>,
}
impl<P: Protocol, T: Transport<P>> EliteRPC<T, P> {
pub fn new(info: &str) -> anyhow::Result<Self> {
let protocol = P::new()?;
let transport = T::new(info, protocol)?;
Ok(Self {
transport,
phantom: PhantomData {},
})
}
pub fn call(
&self,
method: TransportMethod,
request: &P::InnerType,
) -> anyhow::Result<P::InnerType> {
self.transport.call(method, request)
}
}
#[cfg(test)]
mod tests {
use crate::protocol::Protocol;
use crate::transport::{Transport, TransportMethod};
use crate::EliteRPC;
pub struct MockTransport;
#[derive(Clone)]
pub struct MockProtocol;
impl Transport<MockProtocol> for MockTransport {
fn new(_: &str, _: MockProtocol) -> anyhow::Result<Self>
where
Self: Sized,
{
Ok(Self)
}
fn call(
&self,
_: TransportMethod,
_: &<MockProtocol as Protocol>::InnerType,
) -> anyhow::Result<<MockProtocol as Protocol>::InnerType> {
Ok(())
}
}
impl Protocol for MockProtocol {
type InnerType = ();
fn from_request(
&self,
_: &[u8],
_: Option<crate::protocol::Encoding>,
) -> anyhow::Result<Self::InnerType> {
Ok(())
}
fn new() -> anyhow::Result<Self>
where
Self: Sized,
{
Ok(MockProtocol)
}
fn to_request(
&self,
_: &str,
_: &Self::InnerType,
) -> anyhow::Result<(String, Self::InnerType)> {
Ok((String::new(), ()))
}
}
#[test]
pub fn test_init_example() -> anyhow::Result<()> {
let rpc = EliteRPC::<MockTransport, MockProtocol>::new("")?;
let response = rpc.call(TransportMethod::Get("foo".to_owned()), &())?;
assert_eq!(response, ());
Ok(())
}
}