bitfold_core/
shared.rs

1use std::sync::Arc;
2
3/// SharedBytes is a reference-counted, sliceable byte buffer.
4///
5/// It holds an `Arc<[u8]>` plus a (start, len) view, allowing cheap
6/// zero-copy slicing that still dereferences to `&[u8]`.
7#[derive(Clone, Debug, PartialEq, Eq)]
8pub struct SharedBytes {
9    data: Arc<[u8]>,
10    start: usize,
11    len: usize,
12}
13
14impl SharedBytes {
15    /// Creates a new SharedBytes from a Vec by taking ownership.
16    pub fn from_vec(vec: Vec<u8>) -> Self {
17        let arc: Arc<[u8]> = Arc::from(vec.into_boxed_slice());
18        let len = arc.len();
19        Self { data: arc, start: 0, len }
20    }
21
22    /// Creates a new SharedBytes from an Arc<[u8]> covering the full slice.
23    pub fn from_arc(data: Arc<[u8]>) -> Self {
24        let len = data.len();
25        Self { data, start: 0, len }
26    }
27
28    /// Creates a sub-slice view into the current buffer without copying.
29    /// Panics if the requested range is out of bounds.
30    pub fn slice(&self, start: usize, len: usize) -> Self {
31        assert!(start <= self.len, "slice start out of bounds");
32        assert!(start + len <= self.len, "slice end out of bounds");
33        Self { data: self.data.clone(), start: self.start + start, len }
34    }
35
36    /// Returns the current view as a byte slice.
37    pub fn as_slice(&self) -> &[u8] {
38        &self.data[self.start..self.start + self.len]
39    }
40
41    /// Returns the length of the current view.
42    pub fn len(&self) -> usize {
43        self.len
44    }
45
46    /// Returns true if the view is empty.
47    pub fn is_empty(&self) -> bool {
48        self.len == 0
49    }
50
51    /// Returns the inner Arc if the view covers the whole buffer.
52    pub fn into_full_arc(self) -> Option<Arc<[u8]>> {
53        if self.start == 0 && self.len == self.data.len() {
54            Some(self.data)
55        } else {
56            None
57        }
58    }
59}
60
61impl From<Vec<u8>> for SharedBytes {
62    fn from(v: Vec<u8>) -> Self {
63        Self::from_vec(v)
64    }
65}
66
67impl From<Arc<[u8]>> for SharedBytes {
68    fn from(a: Arc<[u8]>) -> Self {
69        Self::from_arc(a)
70    }
71}
72
73impl AsRef<[u8]> for SharedBytes {
74    fn as_ref(&self) -> &[u8] {
75        self.as_slice()
76    }
77}