don't create intermediate Vec's while serializing messages

This commit is contained in:
Milo Turner 2020-03-09 14:28:34 -04:00
parent 6652ddb3d1
commit 87fd190378
2 changed files with 19 additions and 12 deletions

View File

@ -17,7 +17,9 @@ pub struct DesError;
pub trait SerDes: Sized { pub trait SerDes: Sized {
fn des(data: &[u8]) -> Result<Self, DesError>; fn des(data: &[u8]) -> Result<Self, DesError>;
fn ser_into(self) -> Vec<u8>;
// `buf.len()` must be >= `MAX_SERIALIZED_SIZE`
fn ser_to(&self, buf: &mut [u8]) -> usize;
} }
impl SerDes for UpMsg { impl SerDes for UpMsg {
@ -25,23 +27,27 @@ impl SerDes for UpMsg {
Ok(UpMsg::Data(data.into())) Ok(UpMsg::Data(data.into()))
} }
fn ser_into(self) -> Vec<u8> { fn ser_to(&self, buf: &mut [u8]) -> usize {
match self { match self {
UpMsg::Data(data) => data, UpMsg::Data(data) => {
let len = data.len();
buf[..len].copy_from_slice(&data[..]);
len
}
} }
} }
} }
impl SerDes for DownMsg { impl SerDes for DownMsg {
fn des(data: &[u8]) -> Result<Self, DesError> { fn des(data: &[u8]) -> Result<Self, DesError> {
if data == [0] { match data.first() {
Ok(DownMsg::Ack) Some(0) => Ok(DownMsg::Ack),
} else { _ => Err(DesError),
Err(DesError)
} }
} }
fn ser_into(self) -> Vec<u8> { fn ser_to(&self, buf: &mut [u8]) -> usize {
vec![0] buf[0] = 0;
1
} }
} }

View File

@ -55,9 +55,10 @@ impl<F, T> Peer<F, T> {
where where
F: SerDes, F: SerDes,
{ {
let targ = self.targ.ok_or(SendError::NoTarget)?; let mut buf = [0u8; msg::MAX_SERIALIZED_SIZE];
let data = msg.ser_into(); let len = msg.ser_to(&mut buf);
let _n_sent = self.sock.send_to(&data, targ).await?; let who = self.targ.ok_or(SendError::NoTarget)?;
let _n_sent = self.sock.send_to(&buf[..len], who).await?;
Ok(()) Ok(())
} }