fire_stream/packet/
bytes.rs

1use super::{BodyBytes, BodyBytesMut};
2
3use bytes::{Bytes, BytesMut};
4
5
6/// A trait that allows efficient allocation if encryption is
7/// used or not.
8pub trait PacketBytes: std::fmt::Debug {
9	/// Creates a new Bytes instance.
10	///
11	/// It must always have header len available and initialized
12	fn new(header_len: usize) -> Self;
13
14	/// Returns the header Bytes.
15	fn header(&self) -> Bytes<'_>;
16
17	/// Returns the header mutably.
18	fn header_mut(&mut self) -> BytesMut<'_>;
19
20	/// Returns the full header mutably.
21	/// 
22	/// ## Note
23	/// This should only be used to fill the buffer from a reader, in any other
24	/// case you should use `header_mut`.
25	fn full_header_mut(&mut self) -> BytesMut<'_>;
26
27	/// Returns the body.
28	fn body(&self) -> BodyBytes<'_>;
29
30	/// Returns the body mutably.
31	fn body_mut(&mut self) -> BodyBytesMut<'_>;
32
33	/// Returns the full body mutably.
34	/// 
35	/// ## Note
36	/// This should only be used to fill the buffer from a reader, in any other
37	/// case you should use `body_mut`.
38	fn full_body_mut(&mut self) -> BytesMut<'_>;
39}
40
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct PlainBytes {
43	bytes: Vec<u8>,
44	header_len: usize
45}
46
47impl PacketBytes for PlainBytes {
48	fn new(header_len: usize) -> Self {
49		Self {
50			bytes: vec![0; header_len],
51			header_len
52		}
53	}
54
55	fn header(&self) -> Bytes<'_> {
56		self.bytes[..self.header_len].into()
57	}
58
59	fn header_mut(&mut self) -> BytesMut<'_> {
60		(&mut self.bytes[..self.header_len]).into()
61	}
62
63	fn full_header_mut(&mut self) -> BytesMut<'_> {
64		self.header_mut()
65	}
66
67	fn body(&self) -> BodyBytes<'_> {
68		BodyBytes::new(&self.bytes[self.header_len..])
69	}
70
71	fn body_mut(&mut self) -> BodyBytesMut<'_> {
72		BodyBytesMut::new(self.header_len, &mut self.bytes)
73	}
74
75	fn full_body_mut(&mut self) -> BytesMut<'_> {
76		(&mut self.bytes[self.header_len..]).into()
77	}
78}
79
80impl PlainBytes {
81	#[cfg_attr(not(feature = "connection"), allow(dead_code))]
82	pub(crate) fn as_slice(&self) -> &[u8] {
83		&*self.bytes
84	}
85}
86
87
88#[cfg(test)]
89pub(super) mod tests {
90	use super::*;
91	use bytes::{BytesOwned, BytesRead, BytesWrite};
92
93	pub fn test_gen_msg<B: PacketBytes>() {
94		let header = [10u8; 30];
95		let mut bytes = B::new(header.len());
96		bytes.header_mut().write(&header);
97		assert_eq!(bytes.body().len(), 0);
98
99		{
100			let mut body = bytes.body_mut();
101
102			// now i can't use bytes
103			// but body
104
105			body.write_u32(10u32);
106			body.write_u32(20u32);
107		}
108
109		// assert_eq!(bytes.as_slice().len(), 16 + 30 + 16 + 4 + 4);
110
111		assert_eq!(bytes.header().as_slice(), header);
112
113		let mut body = BytesOwned::new();
114		body.write_u32(10);
115		body.write_u32(20);
116		assert_eq!(bytes.body().as_slice(), body.as_slice());
117		assert_eq!(bytes.body().len(), body.len());
118	}
119
120	#[test]
121	fn plain_bytes() {
122		test_gen_msg::<PlainBytes>();
123	}
124}