shared_bytes/
shared_bytes.rs1mod 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 fn try_split_off(&mut self, at: usize) -> Option<Self> {
107 self.as_slice().get(at)?; 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}