use crate::{builders::_internal, error::RpcResult};
use async_std::{net::TcpStream, prelude::*};
use byteorder::{BigEndian, ByteOrder};
use identity::Identity;
pub struct Message {
pub id: Identity,
pub to: String,
pub from: String,
pub data: Vec<u8>,
}
impl Message {
pub fn to_addr(to: &str, from: &str, data: Vec<u8>) -> Self {
Self {
id: Identity::random(),
to: to.into(),
from: from.into(),
data,
}
}
pub fn reply(self, from: String, data: Vec<u8>) -> Self {
Self {
to: self.from,
from,
data,
..self
}
}
}
pub async fn recv(s: &mut TcpStream) -> RpcResult<Message> {
let mut len_buf = vec![0; 8];
s.read_exact(&mut len_buf).await?;
let len = BigEndian::read_u64(&len_buf);
let mut data = vec![0; len as usize];
trace!("Reading {} byte message from stream", len);
s.read_exact(&mut data).await?;
let (id, to, from, data) = _internal::from(data)?;
Ok(Message { id, to, from, data })
}
pub async fn send(s: &mut TcpStream, msg: Message) -> RpcResult<()> {
let mut msg_buf = _internal::to(msg);
let mut buffer = vec![0; 8];
BigEndian::write_u64(&mut buffer, msg_buf.len() as u64);
buffer.append(&mut msg_buf);
trace!("Writing {} (+8) bytes to stream", msg_buf.len());
Ok(s.write_all(&buffer).await?)
}
pub trait WriteToBuf {
fn to_vec(&self) -> RpcResult<Vec<u8>>;
}