commonware_utils/
stable_buf.rs

1//! # Acknowledgements
2//!
3//! This code is inspired by [tokio-uring](https://github.com/tokio-rs/tokio-uring>) at commit 7761222.
4
5use bytes::Bytes;
6use std::ops::Index;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9/// A buffer whose memory is stable as long as its not reallocated.
10pub enum StableBuf {
11    Vec(Vec<u8>),
12    BytesMut(bytes::BytesMut),
13}
14
15impl Default for StableBuf {
16    fn default() -> Self {
17        StableBuf::Vec(Vec::new())
18    }
19}
20
21impl From<Vec<u8>> for StableBuf {
22    fn from(v: Vec<u8>) -> Self {
23        StableBuf::Vec(v)
24    }
25}
26
27impl From<bytes::BytesMut> for StableBuf {
28    fn from(b: bytes::BytesMut) -> Self {
29        StableBuf::BytesMut(b)
30    }
31}
32
33impl From<StableBuf> for Bytes {
34    fn from(buf: StableBuf) -> Self {
35        match buf {
36            StableBuf::Vec(v) => Bytes::from(v),
37            StableBuf::BytesMut(b) => b.freeze(),
38        }
39    }
40}
41
42impl From<StableBuf> for Vec<u8> {
43    fn from(buf: StableBuf) -> Self {
44        match buf {
45            StableBuf::Vec(v) => v,
46            StableBuf::BytesMut(b) => b.to_vec(),
47        }
48    }
49}
50
51impl Index<usize> for StableBuf {
52    type Output = u8;
53
54    fn index(&self, index: usize) -> &Self::Output {
55        match self {
56            StableBuf::Vec(v) => &v[index],
57            StableBuf::BytesMut(b) => &b[index],
58        }
59    }
60}
61
62impl StableBuf {
63    /// Returns a raw pointer to this buffer.
64    pub fn as_mut_ptr(&mut self) -> *mut u8 {
65        match self {
66            StableBuf::Vec(v) => v.as_mut_ptr(),
67            StableBuf::BytesMut(b) => b.as_mut_ptr(),
68        }
69    }
70
71    /// Returns the length of the buffer.
72    pub fn len(&self) -> usize {
73        match self {
74            StableBuf::Vec(v) => v.len(),
75            StableBuf::BytesMut(b) => b.len(),
76        }
77    }
78
79    /// Returns whether this buffer is empty.
80    pub fn is_empty(&self) -> bool {
81        match self {
82            StableBuf::Vec(v) => v.is_empty(),
83            StableBuf::BytesMut(b) => b.is_empty(),
84        }
85    }
86
87    /// Copies the given byte slice into this buffer.
88    /// `src` must not overlap with this buffer.
89    /// Panics if `src` exceeds this buffer's length.
90    pub fn put_slice(&mut self, src: &[u8]) {
91        let dst = self.as_mut_ptr();
92        unsafe {
93            std::ptr::copy_nonoverlapping(src.as_ptr(), dst, src.len());
94        }
95    }
96
97    /// Truncates the buffer to the specified length.
98    pub fn truncate(&mut self, len: usize) {
99        match self {
100            StableBuf::Vec(v) => v.truncate(len),
101            StableBuf::BytesMut(b) => b.truncate(len),
102        }
103    }
104}
105
106impl AsRef<[u8]> for StableBuf {
107    fn as_ref(&self) -> &[u8] {
108        match self {
109            StableBuf::Vec(v) => v.as_ref(),
110            StableBuf::BytesMut(b) => b.as_ref(),
111        }
112    }
113}
114
115impl AsMut<[u8]> for StableBuf {
116    fn as_mut(&mut self) -> &mut [u8] {
117        match self {
118            StableBuf::Vec(v) => v.as_mut(),
119            StableBuf::BytesMut(b) => b.as_mut(),
120        }
121    }
122}