use std::io::{Read, Write};
use crate::message::base::ProtoError;
use crate::message::wire;
use crate::types::Timeval;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WireChunk {
pub timestamp: Timeval,
pub payload: Vec<u8>,
}
impl WireChunk {
pub fn wire_size(&self) -> u32 {
8 + wire::bytes_wire_size(&self.payload)
}
pub fn read_from<R: Read>(r: &mut R) -> Result<Self, ProtoError> {
let timestamp = Timeval::read_from(r)?;
let payload = wire::read_bytes(r)?;
Ok(Self { timestamp, payload })
}
pub fn write_to<W: Write>(&self, w: &mut W) -> Result<(), ProtoError> {
self.timestamp.write_to(w)?;
wire::write_bytes(w, &self.payload)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn round_trip() {
let original = WireChunk {
timestamp: Timeval {
sec: 1000,
usec: 500_000,
},
payload: vec![0xAA, 0xBB, 0xCC, 0xDD],
};
let mut buf = Vec::new();
original.write_to(&mut buf).unwrap();
let mut cursor = std::io::Cursor::new(&buf);
let decoded = WireChunk::read_from(&mut cursor).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn known_bytes() {
let expected: Vec<u8> = vec![
0xE8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xAB, 0xCD, ];
let msg = WireChunk {
timestamp: Timeval { sec: 1000, usec: 0 },
payload: vec![0xAB, 0xCD],
};
let mut buf = Vec::new();
msg.write_to(&mut buf).unwrap();
assert_eq!(buf, expected);
}
#[test]
fn wire_size() {
let msg = WireChunk {
timestamp: Timeval::default(),
payload: vec![0; 960],
};
assert_eq!(msg.wire_size(), 972);
}
}