shared_bytes/
shared_bytes.rs

1mod iter;
2
3pub use self::iter::{IntoIter, Iter};
4
5#[cfg(test)]
6mod tests;
7
8use crate::{owned_slice::OwnedSlice, util::range, IndexOutOfBounds, RangeOfSubset, SharedStr};
9use std::{
10    borrow::{Borrow, Cow},
11    fmt::{self, Debug},
12    ops::{Deref, Range, RangeBounds},
13    sync::Arc,
14};
15
16#[derive(Clone)]
17pub struct SharedBytes(pub(crate) Flavour);
18
19#[derive(Clone)]
20pub(crate) enum Flavour {
21    Static(&'static [u8]),
22    ArcVecSlice(OwnedSlice<Arc<Vec<u8>>, [u8]>),
23    ArcStringSlice(OwnedSlice<Arc<String>, [u8]>),
24}
25
26impl SharedBytes {
27    #[inline]
28    pub const fn new() -> Self {
29        Self(Flavour::Static(b""))
30    }
31
32    #[inline]
33    pub const fn from_static(x: &'static [u8]) -> Self {
34        Self(Flavour::Static(x))
35    }
36
37    #[inline]
38    pub fn from_vec(x: Vec<u8>) -> Self {
39        Self::from_arc_vec(Arc::new(x))
40    }
41
42    #[inline]
43    pub fn from_arc_vec(x: Arc<Vec<u8>>) -> Self {
44        Self(Flavour::ArcVecSlice(OwnedSlice::new(x).unwrap()))
45    }
46
47    #[inline]
48    pub fn from_arc_string(x: Arc<String>) -> Self {
49        Self(Flavour::ArcStringSlice(OwnedSlice::new(x).unwrap()))
50    }
51
52    pub fn into_vec(self) -> Vec<u8> {
53        self.into_static_cow().into_owned()
54    }
55
56    fn into_static_cow(self) -> Cow<'static, [u8]> {
57        match self.0 {
58            Flavour::Static(x) => Cow::Borrowed(x),
59            Flavour::ArcVecSlice(x) => Cow::Owned(x.into_unwrapped(Into::into, ToOwned::to_owned)),
60            Flavour::ArcStringSlice(x) => {
61                Cow::Owned(x.into_unwrapped(Into::into, ToOwned::to_owned))
62            }
63        }
64    }
65
66    #[inline]
67    pub fn as_slice(&self) -> &[u8] {
68        match &self.0 {
69            Flavour::Static(x) => x,
70            Flavour::ArcVecSlice(x) => x,
71            Flavour::ArcStringSlice(x) => x,
72        }
73    }
74
75    pub fn as_static(&self) -> Option<&'static [u8]> {
76        match &self.0 {
77            Flavour::Static(x) => Some(x),
78            _ => None,
79        }
80    }
81
82    pub fn len(&self) -> usize {
83        self.as_slice().len()
84    }
85
86    pub fn is_empty(&self) -> bool {
87        self.as_slice().is_empty()
88    }
89
90    pub fn clear(&mut self) {
91        *self = Self::new()
92    }
93
94    pub fn truncate(&mut self, at: usize) {
95        self.try_slice_mut(..at)
96            .unwrap_or_else(|_| panic!("truncate index '{at}' should be <= len '{}'", self.len()))
97    }
98
99    #[must_use = "consider fn truncate if you don't need the other half"]
100    pub fn split_off(&mut self, at: usize) -> Self {
101        self.try_split_off(at)
102            .unwrap_or_else(|| panic!("split index '{at}' should be <= len '{}'", self.len()))
103    }
104
105    // may be promoted to a pub fn in the future
106    fn try_split_off(&mut self, at: usize) -> Option<Self> {
107        self.as_slice().get(at)?; // ensure `at` is not out of bounds
108        let mut split = self.clone();
109        split.slice_mut(at..);
110        self.slice_mut(..at);
111        Some(split)
112    }
113
114    pub fn range_of_subset(&self, subset: &[u8]) -> Range<usize> {
115        RangeOfSubset::range_of_subset(self.as_slice(), subset)
116    }
117
118    pub fn slice_cloned<R: RangeBounds<usize>>(&self, r: R) -> Self {
119        self.non_generic_slice_cloned(self.slice_range_from_bounds(r))
120    }
121
122    fn non_generic_slice_cloned(&self, range: Range<usize>) -> Self {
123        self.non_generic_try_slice_cloned(range.clone())
124            .unwrap_or_else(|_| self.out_of_bounds_panic(range))
125    }
126
127    pub fn try_slice_cloned<R: RangeBounds<usize>>(&self, r: R) -> Result<Self, IndexOutOfBounds> {
128        self.non_generic_try_slice_cloned(self.slice_range_from_bounds(r))
129    }
130
131    fn non_generic_try_slice_cloned(&self, range: Range<usize>) -> Result<Self, IndexOutOfBounds> {
132        if self.as_slice().get(range.clone()).is_none() {
133            return Err(IndexOutOfBounds::new());
134        }
135        Ok(self.clone().slice_into(range))
136    }
137
138    pub fn slice_into<R: RangeBounds<usize>>(self, r: R) -> Self {
139        let range = self.slice_range_from_bounds(r);
140        self.non_generic_slice_into(range)
141    }
142
143    fn non_generic_slice_into(self, range: Range<usize>) -> Self {
144        self.non_generic_try_slice_into(range.clone())
145            .unwrap_or_else(|this| this.out_of_bounds_panic(range))
146    }
147
148    pub fn try_slice_into<R: RangeBounds<usize>>(self, r: R) -> Result<Self, Self> {
149        let range = self.slice_range_from_bounds(r);
150        self.non_generic_try_slice_into(range)
151    }
152
153    fn non_generic_try_slice_into(mut self, range: Range<usize>) -> Result<Self, Self> {
154        match self.internal_try_slice_mut(range) {
155            Ok(()) => Ok(self),
156            Err(()) => Err(self),
157        }
158    }
159
160    pub fn slice_mut<R: RangeBounds<usize>>(&mut self, r: R) {
161        self.non_generic_slice_mut(self.slice_range_from_bounds(r))
162    }
163
164    fn non_generic_slice_mut(&mut self, range: Range<usize>) {
165        self.internal_try_slice_mut(range.clone())
166            .unwrap_or_else(|()| self.out_of_bounds_panic(range))
167    }
168
169    pub fn try_slice_mut<R: RangeBounds<usize>>(&mut self, r: R) -> Result<(), IndexOutOfBounds> {
170        self.non_generic_try_slice_mut(self.slice_range_from_bounds(r))
171    }
172
173    fn non_generic_try_slice_mut(&mut self, range: Range<usize>) -> Result<(), IndexOutOfBounds> {
174        self.internal_try_slice_mut(range)
175            .map_err(|()| IndexOutOfBounds::new())
176    }
177
178    fn slice_range_from_bounds<R: RangeBounds<usize>>(&self, r: R) -> Range<usize> {
179        range::from_slice_bounds(r, || self.len())
180    }
181
182    fn out_of_bounds_panic<R: RangeBounds<usize> + Debug, T>(&self, range: R) -> T {
183        let length = self.len();
184        panic!("slice range {range:?} is out of bounds for length {length}")
185    }
186
187    #[must_use = "`internal_try_slice_mut` may fail to mutate `self`"]
188    fn internal_try_slice_mut(&mut self, range: Range<usize>) -> Result<(), ()> {
189        match &mut self.0 {
190            Flavour::Static(old) => match old.get(range) {
191                None => Err(()),
192                Some(new) => {
193                    *old = new;
194                    Ok(())
195                }
196            },
197            Flavour::ArcVecSlice(x) => x.try_slice_mut(range),
198            Flavour::ArcStringSlice(x) => x.try_slice_mut(range),
199        }
200    }
201
202    pub fn iter(&self) -> Iter {
203        Iter::new(self.as_slice())
204    }
205}
206
207impl AsRef<[u8]> for SharedBytes {
208    #[inline]
209    fn as_ref(&self) -> &[u8] {
210        self.as_slice()
211    }
212}
213
214impl Borrow<[u8]> for SharedBytes {
215    #[inline]
216    fn borrow(&self) -> &[u8] {
217        self.as_slice()
218    }
219}
220
221impl Debug for SharedBytes {
222    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223        Debug::fmt(self.as_slice(), f)
224    }
225}
226
227impl Default for SharedBytes {
228    #[inline]
229    fn default() -> Self {
230        Self::new()
231    }
232}
233
234impl Deref for SharedBytes {
235    type Target = [u8];
236
237    #[inline]
238    fn deref(&self) -> &Self::Target {
239        self.as_slice()
240    }
241}
242
243impl Eq for SharedBytes {}
244
245impl PartialEq for SharedBytes {
246    #[inline]
247    fn eq(&self, other: &Self) -> bool {
248        self.as_slice() == other.as_slice()
249    }
250}
251
252impl<Other: ?Sized> PartialEq<&Other> for SharedBytes
253where
254    Self: PartialEq<Other>,
255{
256    #[inline]
257    fn eq(&self, other: &&Other) -> bool {
258        self == *other
259    }
260}
261
262impl PartialEq<[u8]> for SharedBytes {
263    #[inline]
264    fn eq(&self, other: &[u8]) -> bool {
265        self.as_slice() == other
266    }
267}
268
269impl<const N: usize> PartialEq<[u8; N]> for SharedBytes {
270    #[inline]
271    fn eq(&self, other: &[u8; N]) -> bool {
272        self.as_slice() == other.as_slice()
273    }
274}
275
276impl PartialEq<Vec<u8>> for SharedBytes {
277    #[inline]
278    fn eq(&self, other: &Vec<u8>) -> bool {
279        self.as_slice() == other.as_slice()
280    }
281}
282
283impl PartialEq<str> for SharedBytes {
284    #[inline]
285    fn eq(&self, other: &str) -> bool {
286        self.as_slice() == other.as_bytes()
287    }
288}
289
290impl PartialEq<String> for SharedBytes {
291    #[inline]
292    fn eq(&self, other: &String) -> bool {
293        self.as_slice() == other.as_bytes()
294    }
295}
296
297impl std::hash::Hash for SharedBytes {
298    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
299        self.as_slice().hash(state)
300    }
301}
302
303impl From<&'static [u8]> for SharedBytes {
304    #[inline]
305    fn from(x: &'static [u8]) -> Self {
306        Self::from_static(x)
307    }
308}
309
310impl From<Vec<u8>> for SharedBytes {
311    #[inline]
312    fn from(x: Vec<u8>) -> Self {
313        Self::from_vec(x)
314    }
315}
316
317impl From<Arc<Vec<u8>>> for SharedBytes {
318    #[inline]
319    fn from(x: Arc<Vec<u8>>) -> Self {
320        Self::from_arc_vec(x)
321    }
322}
323
324impl From<SharedStr> for SharedBytes {
325    fn from(x: SharedStr) -> Self {
326        use crate::shared_str::Flavour::*;
327        Self(match x.0 {
328            Static(x) => Flavour::Static(x.as_bytes()),
329            ArcVecSlice(x) => Flavour::ArcVecSlice(x.try_map_output().unwrap()),
330            ArcStringSlice(x) => Flavour::ArcStringSlice(x.try_map_output().unwrap()),
331        })
332    }
333}
334
335impl From<&'static str> for SharedBytes {
336    #[inline]
337    fn from(x: &'static str) -> Self {
338        Self::from_static(x.as_bytes())
339    }
340}
341
342impl From<String> for SharedBytes {
343    #[inline]
344    fn from(x: String) -> Self {
345        Self::from_vec(x.into_bytes())
346    }
347}
348
349impl From<Arc<String>> for SharedBytes {
350    #[inline]
351    fn from(x: Arc<String>) -> Self {
352        Self::from_arc_string(x)
353    }
354}
355
356impl From<SharedBytes> for Vec<u8> {
357    fn from(x: SharedBytes) -> Self {
358        x.into_vec()
359    }
360}
361
362impl FromIterator<u8> for SharedBytes {
363    #[inline]
364    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
365        Self::from_vec(iter.into_iter().collect())
366    }
367}
368
369impl<'a> IntoIterator for &'a SharedBytes {
370    type Item = u8;
371
372    type IntoIter = Iter<'a>;
373
374    fn into_iter(self) -> Self::IntoIter {
375        self.iter()
376    }
377}
378
379impl IntoIterator for SharedBytes {
380    type Item = u8;
381
382    type IntoIter = IntoIter;
383
384    fn into_iter(self) -> IntoIter {
385        IntoIter(self)
386    }
387}