use super::{BodyBytes, BodyBytesMut};
use bytes::{Bytes, BytesMut};
pub trait PacketBytes: std::fmt::Debug {
fn new(header_len: usize) -> Self;
fn header(&self) -> Bytes<'_>;
fn header_mut(&mut self) -> BytesMut<'_>;
fn full_header_mut(&mut self) -> BytesMut<'_>;
fn body(&self) -> BodyBytes<'_>;
fn body_mut(&mut self) -> BodyBytesMut<'_>;
fn full_body_mut(&mut self) -> BytesMut<'_>;
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PlainBytes {
bytes: Vec<u8>,
header_len: usize
}
impl PacketBytes for PlainBytes {
fn new(header_len: usize) -> Self {
Self {
bytes: vec![0; header_len],
header_len
}
}
fn header(&self) -> Bytes<'_> {
self.bytes[..self.header_len].into()
}
fn header_mut(&mut self) -> BytesMut<'_> {
(&mut self.bytes[..self.header_len]).into()
}
fn full_header_mut(&mut self) -> BytesMut<'_> {
self.header_mut()
}
fn body(&self) -> BodyBytes<'_> {
BodyBytes::new(&self.bytes[self.header_len..])
}
fn body_mut(&mut self) -> BodyBytesMut<'_> {
BodyBytesMut::new(self.header_len, &mut self.bytes)
}
fn full_body_mut(&mut self) -> BytesMut<'_> {
(&mut self.bytes[self.header_len..]).into()
}
}
impl PlainBytes {
#[cfg_attr(not(feature = "connection"), allow(dead_code))]
pub(crate) fn as_slice(&self) -> &[u8] {
&*self.bytes
}
}
#[cfg(test)]
pub(super) mod tests {
use super::*;
use bytes::{BytesOwned, BytesRead, BytesWrite};
pub fn test_gen_msg<B: PacketBytes>() {
let header = [10u8; 30];
let mut bytes = B::new(header.len());
bytes.header_mut().write(&header);
assert_eq!(bytes.body().len(), 0);
{
let mut body = bytes.body_mut();
body.write_u32(10u32);
body.write_u32(20u32);
}
assert_eq!(bytes.header().as_slice(), header);
let mut body = BytesOwned::new();
body.write_u32(10);
body.write_u32(20);
assert_eq!(bytes.body().as_slice(), body.as_slice());
assert_eq!(bytes.body().len(), body.len());
}
#[test]
fn plain_bytes() {
test_gen_msg::<PlainBytes>();
}
}