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