ringo_buff/vec.rs
1use crate::{CircularBuffer, Storage};
2
3impl crate::sealed::StorageBase for Vec<u8> {}
4
5impl Storage for Vec<u8> {
6 fn len(&self) -> usize {
7 self.len()
8 }
9
10 fn as_slice(&self) -> &[u8] {
11 self.as_slice()
12 }
13
14 fn as_mut_slice(&mut self) -> &mut [u8] {
15 self.as_mut_slice()
16 }
17
18 fn split_at(&self, offset: usize) -> (&[u8], &[u8]) {
19 self.as_slice().split_at(offset)
20 }
21
22 fn split_at_mut(&mut self, offset: usize) -> (&mut [u8], &mut [u8]) {
23 self.as_mut_slice().split_at_mut(offset)
24 }
25}
26
27/// A circular buffer backed by a heap-allocated `Vec<u8>`.
28///
29/// Requires the `alloc` feature (enabled by default).
30pub type HeapBuffer = CircularBuffer<Vec<u8>>;
31
32impl HeapBuffer {
33 /// Creates a new buffer with the specified capacity.
34 ///
35 /// This allocates a `Vec` of `capacity` bytes filled with zeros.
36 ///
37 /// # Panics
38 ///
39 /// Panics if `capacity` is 0.
40 ///
41 /// # Examples
42 ///
43 /// ```
44 /// use ringo_buff::HeapBuffer;
45 ///
46 /// let buf = HeapBuffer::new(1024);
47 /// assert_eq!(buf.capacity(), 1024);
48 /// ```
49 pub fn new(capacity: usize) -> Self {
50 assert!(capacity > 0);
51 Self::_new_with_storage(vec![0u8; capacity])
52 }
53
54 /// Attempts to resize the buffer to a `new_capacity`.
55 ///
56 /// # Growing
57 /// If `new_capacity` is larger than the current capacity, the buffer is extended.
58 ///
59 /// # Shrinking
60 /// If `new_capacity` is smaller, the buffer attempts to shrink.
61 /// * This operation forces the buffer to become contiguous (see [`make_contiguous`](CircularBuffer::make_contiguous)).
62 /// * The operation fails if the active data (`remaining()`) is larger than `new_capacity`.
63 ///
64 /// # Errors
65 ///
66 /// Returns `Err(usize)` if the buffer cannot be shrunk because it currently holds too much data.
67 /// The error value is the number of bytes that must be consumed (read) before this resize can succeed.
68 ///
69 /// # Panics
70 ///
71 /// Panics if `new_capacity` is 0.
72 pub fn try_resize(&mut self, new_capacity: usize) -> Result<(), usize> {
73 assert!(new_capacity > 0);
74 if new_capacity >= self.capacity() {
75 // growing
76 self.bytes.resize(new_capacity, 0u8);
77 } else {
78 // shrinking
79 if self.remaining() > new_capacity {
80 // not enough empty space to shrink
81 let extra_bytes_needed = self.remaining() - new_capacity;
82 return Err(extra_bytes_needed);
83 }
84 self.make_contiguous();
85 self.bytes.truncate(new_capacity);
86 }
87 Ok(())
88 }
89}
90
91impl From<Vec<u8>> for HeapBuffer {
92 /// Converts an existing `Vec<u8>` into a `HeapBuffer`, reusing the `Vec` as the storage mechanism for the buffer.
93 fn from(value: Vec<u8>) -> Self {
94 assert!(value.capacity() > 0);
95 Self::_new_with_storage(value)
96 }
97}