1use alloc::vec::Vec;
16
17#[derive(Default)]
18pub struct Writer<'a> {
19 owned: Vec<u8>,
20 chunks: Vec<Chunk<'a>>,
21}
22
23impl<'a> Writer<'a> {
24 pub(crate) fn new() -> Self {
25 Writer::default()
26 }
27
28 pub(crate) fn put_share(&mut self, data: &'a [u8]) {
29 self.chunks.push(Chunk::Borrowed(data));
30 }
31
32 pub(crate) fn put_copy(&mut self, data: &[u8]) {
33 if !matches!(self.chunks.last(), Some(Chunk::Owned { .. })) {
37 self.chunks.push(Chunk::Owned { offset: self.owned.len(), length: 0 });
38 }
39 let length = match self.chunks.last_mut() {
40 Some(Chunk::Owned { length, .. }) => length,
41 _ => unreachable!(),
42 };
43 self.owned.extend_from_slice(data);
44 *length += data.len();
45 }
46
47 pub(crate) fn finalize(self, data: &mut Vec<u8>) {
48 data.reserve_exact(self.chunks.iter().map(|x| x.len()).sum());
49 for chunk in self.chunks {
50 data.extend_from_slice(chunk.slice(&self.owned));
51 }
52 }
53}
54
55enum Chunk<'a> {
56 Owned { offset: usize, length: usize },
57 Borrowed(&'a [u8]),
58}
59
60impl<'a> Chunk<'a> {
61 fn slice(&self, owned: &'a [u8]) -> &'a [u8] {
62 match *self {
63 Chunk::Owned { offset, length } => &owned[offset ..][.. length],
64 Chunk::Borrowed(x) => x,
65 }
66 }
67
68 fn len(&self) -> usize {
69 match *self {
70 Chunk::Owned { length, .. } => length,
71 Chunk::Borrowed(x) => x.len(),
72 }
73 }
74}