libzrpc 0.1.0

A RPC library for Rust
Documentation
use std::{net::Ipv4Addr, time::Duration};

use tokio::{net::TcpStream, time::timeout};

use crate::{
    error::ZRpcError,
    transport::tcp::TcpTransport,
    types::{dt::ZRpcDt, proc_error::ProcedureError, req::ZRpcReq},
};

pub struct ZRpcClient {
    transport: TcpTransport,
    timeout: Duration,
}

impl ZRpcClient {
    pub async fn new(addr: (Ipv4Addr, u16)) -> Result<Self, ZRpcError> {
        let stream = TcpStream::connect(addr).await.map_err(ZRpcError::Io)?;
        let transport = TcpTransport::new(stream);

        Ok(Self {
            transport,
            timeout: Duration::from_secs(30),
        })
    }

    pub fn set_timeout(&mut self, duration: Duration) {
        self.timeout = duration;
    }

    pub async fn call(&mut self, proc: &str, params: Vec<ZRpcDt>) -> Result<ZRpcDt, ZRpcError> {
        self.execute(ZRpcReq::new(proc, params)).await
    }

    async fn execute(&mut self, req: ZRpcReq) -> Result<ZRpcDt, ZRpcError> {
        let bytes =
            bincode::serialize(&req).map_err(|e| ZRpcError::Serialization(e.to_string()))?;

        timeout(self.timeout, async {
            self.transport.send(&bytes).await?;

            let bytes = self.transport.receive().await?;
            let res: Result<ZRpcDt, ProcedureError> = bincode::deserialize(&bytes)
                .map_err(|e| ZRpcError::Serialization(e.to_string()))?;

            res.map_err(ZRpcError::Procedure)
        })
        .await
        .map_err(|_| ZRpcError::TimeoutError)?
    }
}