1#[derive(Clone)]
2pub struct Buffer(Vec<u8>);
3
4impl Buffer {
5 pub fn build<T: AsRef<[U]>, U: AsRef<[u8]>>(parts: T) -> Self {
9 let parts = parts.as_ref();
10 let parts_len = parts.len();
11 let bytes_total = parts.into_iter().fold(0usize, |acc, part| acc + part.as_ref().len());
12 Self::build_with_size_hint(parts, (parts_len * std::mem::size_of::<usize>()) + bytes_total)
13 }
14
15 pub fn build_with_size_hint<T: AsRef<[U]>, U: AsRef<[u8]>>(parts: T, size_hint: usize) -> Self {
17 let parts = parts.as_ref();
18
19 let mut buffer = Vec::with_capacity(size_hint);
20
21 for part in parts {
22 let part = part.as_ref();
23 let part_len = part.len();
24 buffer.extend_from_slice(&part_len.to_le_bytes());
25 buffer.extend_from_slice(part);
26 }
27
28 buffer.shrink_to_fit();
29
30 Buffer(buffer)
31 }
32
33 pub fn into_inner(self) -> Vec<u8> {
35 self.0
36 }
37}
38
39pub struct BufferIterator<'a> {
41 buffer: &'a [u8],
42 offset: usize,
43}
44
45impl<'a> IntoIterator for &'a Buffer {
46 type Item = &'a [u8];
47 type IntoIter = BufferIterator<'a>;
48
49 fn into_iter(self) -> Self::IntoIter {
50 BufferIterator { buffer: &self.0, offset: 0 }
51 }
52}
53
54impl<'a> Iterator for BufferIterator<'a> {
55 type Item = &'a [u8];
56 fn next(&mut self) -> Option<Self::Item> {
57 use std::convert::TryInto;
58
59 if self.buffer[self.offset..].is_empty() {
60 return None;
61 }
62
63 let bytes_start = self.offset + std::mem::size_of::<usize>();
64 let len = usize::from_le_bytes(
65 self.buffer[self.offset..bytes_start].try_into().expect("Must be `usize`"),
66 ) as usize;
67 self.offset = bytes_start + len;
68
69 Some(&self.buffer[bytes_start..self.offset])
70 }
71}