Skip to main content

libtw2_buffer/impls/
vec.rs

1use crate::Buffer;
2use crate::BufferRef;
3use crate::ToBufferRef;
4use std::slice;
5
6/// The intermediate step from a `Vec` to a `BufferRef`.
7pub struct VecBuffer<'data> {
8    // Will only touch the length of the `Vec` through this reference, except
9    // in `VecBuffer::buffer`.
10    vec: &'data mut Vec<u8>,
11    initialized: usize,
12}
13
14impl<'data> VecBuffer<'data> {
15    fn new(vec: &'data mut Vec<u8>) -> VecBuffer<'data> {
16        VecBuffer {
17            vec: vec,
18            initialized: 0,
19        }
20    }
21    fn buffer<'size>(&'size mut self) -> BufferRef<'data, 'size> {
22        let len = self.vec.len();
23        let remaining = self.vec.capacity() - len;
24        unsafe {
25            let start = self.vec.as_mut_ptr().offset(len as isize);
26            // This is unsafe, we now have two unique (mutable) references to
27            // the same `Vec`. However, we will only access `self.vec.len`
28            // through `self` and only the contents through the `BufferRef`.
29            BufferRef::new(
30                slice::from_raw_parts_mut(start, remaining),
31                &mut self.initialized,
32            )
33        }
34    }
35}
36
37impl<'data> Drop for VecBuffer<'data> {
38    fn drop(&mut self) {
39        let len = self.vec.len();
40        unsafe {
41            self.vec.set_len(len + self.initialized);
42        }
43    }
44}
45
46impl<'data> Buffer<'data> for &'data mut Vec<u8> {
47    type Intermediate = VecBuffer<'data>;
48    fn to_to_buffer_ref(self) -> Self::Intermediate {
49        VecBuffer::new(self)
50    }
51}
52
53impl<'data> ToBufferRef<'data> for VecBuffer<'data> {
54    fn to_buffer_ref<'size>(&'size mut self) -> BufferRef<'data, 'size> {
55        self.buffer()
56    }
57}