arc_slice/
buffer.rs

1//! Generic slice and buffer abstractions used by [`ArcSlice`] and [`ArcSliceMut`].
2//!
3//! [`ArcSlice`]: crate::ArcSlice
4//! [`ArcSliceMut`]: crate::ArcSliceMut
5use alloc::{alloc::realloc, boxed::Box, string::String, vec::Vec};
6use core::{
7    alloc::{Layout, LayoutError},
8    any::Any,
9    cmp::max,
10    convert::Infallible,
11    mem,
12    mem::ManuallyDrop,
13    ops::{Deref, DerefMut},
14    ptr,
15    ptr::{addr_of, addr_of_mut, NonNull},
16    slice,
17};
18
19pub(crate) use crate::buffer::private::DynBuffer;
20#[allow(unused_imports)]
21use crate::msrv::{ConstPtrExt, NonNullExt, OffsetFromUnsignedExt, SlicePtrExt};
22use crate::{
23    error::TryReserveError,
24    macros::assume,
25    slice_mut::TryReserveResult,
26    utils::{assert_checked, NewChecked},
27};
28
29/// A slice, e.g. `[T]` or `str`.
30///
31/// # Safety
32///
33/// - [`into_vec`](Self::into_vec) must be *pure*, i.e. `mem::forget(S::into_vec(ptr::read(vec_ptr)))`
34///   should not invalidate memory behind `vec_ptr`.
35/// - If [`try_from_slice_mut`](Self::try_from_slice_mut) returns `Ok` for a slice, then
36///   [`try_from_slice`](Self::try_from_slice) must also return `Ok` for that slice.
37pub unsafe trait Slice: Send + Sync + 'static {
38    /// The slice item, e.g. `T` for `[T]` or `u8` for `str`.
39    type Item: Send + Sync + 'static;
40    /// The associated vector to the slice type, e.g. `Vec<T>` for `[T]` or `String` for `str`.
41    type Vec: BufferMut<Self>;
42
43    /// Converts a slice to its underlying item slice.
44    fn to_slice(&self) -> &[Self::Item];
45    /// Converts a mutable slice to its underlying item slice.
46    ///
47    /// # Safety
48    ///
49    /// The item slice is never mutated, as it is only used for storage.
50    unsafe fn to_slice_mut(&mut self) -> &mut [Self::Item];
51    /// Converts a boxed slice to its underlying boxed item slice.
52    fn into_boxed_slice(self: Box<Self>) -> Box<[Self::Item]>;
53    /// Converts a vector to its underlying item vector.
54    fn into_vec(vec: Self::Vec) -> Vec<Self::Item>;
55
56    /// Converts back a slice from its underlying item slice.
57    ///
58    /// # Safety
59    ///
60    /// The item slice must be valid as if it has been obtained from [`Self::to_slice`].
61    unsafe fn from_slice_unchecked(slice: &[Self::Item]) -> &Self;
62    /// Converts back a mutable slice from its underlying item slice.
63    ///
64    /// # Safety
65    ///
66    /// The item slice must be valid as if it has been obtained from [`Self::to_slice_mut`].
67    unsafe fn from_slice_mut_unchecked(slice: &mut [Self::Item]) -> &mut Self;
68    /// Converts back a boxed slice from its underlying boxed item slice.
69    ///
70    /// # Safety
71    ///
72    /// The boxed item slice must be valid as if it has been obtained from
73    /// [`Self::into_boxed_slice`].
74    unsafe fn from_boxed_slice_unchecked(boxed: Box<[Self::Item]>) -> Box<Self>;
75    /// Converts back a vector from its underlying item vector.
76    ///
77    /// # Safety
78    ///
79    /// The vector must be valid as if it has been obtained from [`Self::into_vec`].
80    unsafe fn from_vec_unchecked(vec: Vec<Self::Item>) -> Self::Vec;
81
82    /// Error which can occur when attempting to convert an item slice to the given slice type.
83    type TryFromSliceError;
84    /// Try converting an item slice to the given slice type.
85    fn try_from_slice(slice: &[Self::Item]) -> Result<&Self, Self::TryFromSliceError>;
86    /// Tries converting a mutable item slice to the given slice type.
87    fn try_from_slice_mut(slice: &mut [Self::Item]) -> Result<&mut Self, Self::TryFromSliceError>;
88}
89
90pub(crate) trait SliceExt: Slice {
91    fn as_ptr(&self) -> NonNull<Self::Item> {
92        NonNull::new_checked(self.to_slice().as_ptr().cast_mut())
93    }
94    fn as_mut_ptr(&mut self) -> NonNull<Self::Item> {
95        NonNull::new_checked(unsafe { self.to_slice_mut().as_mut_ptr() })
96    }
97    fn len(&self) -> usize {
98        self.to_slice().len()
99    }
100    fn is_empty(&self) -> bool {
101        self.len() == 0
102    }
103    fn to_raw_parts(&self) -> (NonNull<Self::Item>, usize) {
104        (self.as_ptr(), self.len())
105    }
106    fn to_raw_parts_mut(&mut self) -> (NonNull<Self::Item>, usize) {
107        (self.as_mut_ptr(), self.len())
108    }
109    unsafe fn from_raw_parts<'a>(start: NonNull<Self::Item>, length: usize) -> &'a Self {
110        unsafe { Self::from_slice_unchecked(slice::from_raw_parts(start.as_ptr(), length)) }
111    }
112    unsafe fn from_raw_parts_mut<'a>(start: NonNull<Self::Item>, length: usize) -> &'a mut Self {
113        unsafe { Self::from_slice_mut_unchecked(slice::from_raw_parts_mut(start.as_ptr(), length)) }
114    }
115    // use this instead of `BufferMutExt::as_mut_ptr` as the pointer
116    // is not invalidated when the vector is moved
117    fn vec_start(vec: &mut Self::Vec) -> NonNull<Self::Item> {
118        let mut vec = ManuallyDrop::new(Self::into_vec(unsafe { ptr::read(vec) }));
119        NonNull::new_checked(vec.as_mut_ptr())
120    }
121    fn needs_drop() -> bool {
122        mem::needs_drop::<Self::Item>()
123    }
124}
125
126impl<S: Slice + ?Sized> SliceExt for S {}
127
128/// A slice that can be empty.
129///
130/// # Safety
131///
132/// `Slice::try_from_slice(&[])`/`Slice::try_from_slice_mut(&mut [])` must be ok.
133pub unsafe trait Emptyable: Slice {}
134
135/// A slice that can be safely initialized from an all-zero byte-pattern.
136///
137/// # Safety
138///
139/// An item slice allocated with [`alloc_zeroed`](alloc::alloc::alloc_zeroed) must be valid and
140/// safely interpretable as the slice type without undefined behavior.
141pub unsafe trait Zeroable: Slice {}
142
143/// A slice that can be split into smaller subslices.
144///
145/// # Safety
146///
147/// If [`Self::check_subslice`] (or other derived methods) doesn't panic, then the subslice
148/// with the given range must be valid.
149pub unsafe trait Subsliceable: Slice {
150    /// Check if a subslice is valid.
151    ///
152    /// # Safety
153    ///
154    /// `start..end` must be a valid range of the item slice returned by [`Slice::to_slice`].
155    unsafe fn check_subslice(&self, start: usize, end: usize);
156    /// Same as `self.check_subslice(offset, self.to_slice().len())`.
157    ///
158    /// # Safety
159    ///
160    /// See [`Self::check_subslice`].
161    unsafe fn check_advance(&self, offset: usize) {
162        unsafe { self.check_subslice(offset, self.len()) }
163    }
164    /// Same as `self.check_subslice(0, offset))`.
165    ///
166    /// # Safety
167    ///
168    /// See [`Self::check_subslice`].
169    unsafe fn check_truncate(&self, len: usize) {
170        unsafe { self.check_subslice(0, len) }
171    }
172    /// Same as `{ self.check_subslice(0, at)); self.check_subslice(at, self.to_slice().len()) }`.
173    ///
174    /// # Safety
175    ///
176    /// See [`Self::check_subslice`].
177    unsafe fn check_split(&self, at: usize) {
178        unsafe { self.check_subslice(0, at) };
179        unsafe { self.check_subslice(at, self.len()) };
180    }
181}
182
183/// A slice that can be concatenated.
184///
185/// # Safety
186///
187/// The concatenation of two slices must be a valid slice.
188pub unsafe trait Concatenable: Slice {}
189
190/// A slice that can be extended with arbitrary items.
191///
192/// # Safety
193///
194/// The concatenation of a slice with an additional item must be a valid slice.
195pub unsafe trait Extendable: Concatenable {}
196
197/// A slice that can be deserialized according to the [`serde` data model]
198///
199/// [`serde` data model]: https://serde.rs/data-model.html
200#[cfg(feature = "serde")]
201pub trait Deserializable: Slice
202where
203    Self::Item: for<'a> serde::Deserialize<'a>,
204    Self::TryFromSliceError: core::fmt::Display,
205{
206    /// Deserializes a slice with the given visitor.
207    fn deserialize<'de, D: serde::Deserializer<'de>, V: serde::de::Visitor<'de>>(
208        deserializer: D,
209        visitor: V,
210    ) -> Result<V::Value, D::Error>;
211    /// What data the visitor expects to receive.
212    fn expecting(f: &mut core::fmt::Formatter) -> core::fmt::Result;
213    /// Deserializes a slice from bytes.
214    fn deserialize_from_bytes<E: serde::de::Error>(bytes: &[u8]) -> Result<&Self, E>;
215    /// Deserializes a vector from owned bytes.
216    fn deserialize_from_byte_buf<E: serde::de::Error>(bytes: Vec<u8>) -> Result<Self::Vec, E>;
217    /// Deserializes a slice from string.
218    fn deserialize_from_str<E: serde::de::Error>(s: &str) -> Result<&Self, E>;
219    /// Deserializes a slice from owned string.
220    fn deserialize_from_string<E: serde::de::Error>(s: String) -> Result<Self::Vec, E>;
221    /// Tries deserializing a slice from a sequence.
222    ///
223    /// The sequence will be collected into an `ArcSliceMut<[S::Item]>` before calling
224    /// [`ArcSliceMut::try_from_arc_slice_mut`](crate::ArcSliceMut::try_from_arc_slice_mut).
225    fn try_deserialize_from_seq() -> bool;
226}
227
228unsafe impl<T: Send + Sync + 'static> Slice for [T] {
229    type Item = T;
230    type Vec = Vec<T>;
231
232    fn to_slice(&self) -> &[Self::Item] {
233        self
234    }
235    unsafe fn to_slice_mut(&mut self) -> &mut [Self::Item] {
236        self
237    }
238    fn into_boxed_slice(self: Box<Self>) -> Box<[Self::Item]> {
239        self
240    }
241    fn into_vec(vec: Self::Vec) -> Vec<Self::Item> {
242        vec
243    }
244
245    unsafe fn from_slice_unchecked(slice: &[Self::Item]) -> &Self {
246        slice
247    }
248    unsafe fn from_slice_mut_unchecked(slice: &mut [Self::Item]) -> &mut Self {
249        slice
250    }
251    unsafe fn from_boxed_slice_unchecked(boxed: Box<[Self::Item]>) -> Box<Self> {
252        boxed
253    }
254    unsafe fn from_vec_unchecked(vec: Vec<Self::Item>) -> Self::Vec {
255        vec
256    }
257
258    type TryFromSliceError = Infallible;
259    fn try_from_slice(slice: &[Self::Item]) -> Result<&Self, Self::TryFromSliceError> {
260        Ok(slice)
261    }
262    fn try_from_slice_mut(slice: &mut [Self::Item]) -> Result<&mut Self, Self::TryFromSliceError> {
263        Ok(slice)
264    }
265}
266
267unsafe impl<T: Send + Sync + 'static> Emptyable for [T] {}
268unsafe impl Emptyable for str {}
269
270#[cfg(feature = "bytemuck")]
271unsafe impl<T: bytemuck::Zeroable + Send + Sync + 'static> Zeroable for [T] {}
272#[cfg(not(feature = "bytemuck"))]
273unsafe impl Zeroable for [u8] {}
274unsafe impl Zeroable for str {}
275
276unsafe impl<T: Send + Sync + 'static> Subsliceable for [T] {
277    unsafe fn check_subslice(&self, _start: usize, _end: usize) {}
278}
279
280unsafe impl<T: Send + Sync + 'static> Concatenable for [T] {}
281
282unsafe impl<T: Send + Sync + 'static> Extendable for [T] {}
283
284#[cfg(feature = "serde")]
285fn invalid_type<T: for<'a> serde::Deserialize<'a> + Send + Sync + 'static, E: serde::de::Error>(
286    unexpected: serde::de::Unexpected,
287) -> E {
288    struct Expected<T>(core::marker::PhantomData<T>);
289    impl<T: for<'a> serde::Deserialize<'a> + Send + Sync + 'static> serde::de::Expected
290        for Expected<T>
291    {
292        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
293            <[T]>::expecting(f)
294        }
295    }
296    E::invalid_type(unexpected, &Expected(core::marker::PhantomData::<T>))
297}
298
299#[cfg(feature = "serde")]
300impl<T: for<'a> serde::Deserialize<'a> + Send + Sync + 'static> Deserializable for [T] {
301    fn deserialize<'de, D: serde::Deserializer<'de>, V: serde::de::Visitor<'de>>(
302        deserializer: D,
303        visitor: V,
304    ) -> Result<V::Value, D::Error> {
305        if crate::macros::is!(T, u8) {
306            deserializer.deserialize_byte_buf(visitor)
307        } else {
308            deserializer.deserialize_seq(visitor)
309        }
310    }
311    fn expecting(f: &mut core::fmt::Formatter) -> core::fmt::Result {
312        if crate::macros::is!(T, u8) {
313            write!(f, "a byte string")
314        } else {
315            write!(f, "a sequence")
316        }
317    }
318    fn deserialize_from_bytes<E: serde::de::Error>(bytes: &[u8]) -> Result<&Self, E> {
319        if crate::macros::is!(T, u8) {
320            Ok(unsafe { bytes.align_to().1 })
321        } else {
322            Err(invalid_type::<T, E>(serde::de::Unexpected::Bytes(bytes)))
323        }
324    }
325    fn deserialize_from_byte_buf<E: serde::de::Error>(bytes: Vec<u8>) -> Result<Self::Vec, E> {
326        crate::utils::try_transmute(bytes)
327            .map_err(|bytes| invalid_type::<T, E>(serde::de::Unexpected::Bytes(&bytes)))
328    }
329    fn deserialize_from_str<E: serde::de::Error>(s: &str) -> Result<&Self, E> {
330        Err(invalid_type::<T, E>(serde::de::Unexpected::Str(s)))
331    }
332    fn deserialize_from_string<E: serde::de::Error>(s: String) -> Result<Self::Vec, E> {
333        Err(invalid_type::<T, E>(serde::de::Unexpected::Str(&s)))
334    }
335    fn try_deserialize_from_seq() -> bool {
336        crate::macros::is_not!(T, u8)
337    }
338}
339
340unsafe impl Slice for str {
341    type Item = u8;
342    type Vec = String;
343
344    fn to_slice(&self) -> &[Self::Item] {
345        self.as_bytes()
346    }
347    unsafe fn to_slice_mut(&mut self) -> &mut [Self::Item] {
348        unsafe { self.as_bytes_mut() }
349    }
350    fn into_boxed_slice(self: Box<Self>) -> Box<[Self::Item]> {
351        self.into_boxed_bytes()
352    }
353    fn into_vec(vec: Self::Vec) -> Vec<Self::Item> {
354        vec.into_bytes()
355    }
356
357    unsafe fn from_slice_unchecked(slice: &[Self::Item]) -> &Self {
358        unsafe { core::str::from_utf8_unchecked(slice) }
359    }
360    unsafe fn from_slice_mut_unchecked(slice: &mut [Self::Item]) -> &mut Self {
361        unsafe { core::str::from_utf8_unchecked_mut(slice) }
362    }
363    unsafe fn from_boxed_slice_unchecked(boxed: Box<[Self::Item]>) -> Box<Self> {
364        unsafe { alloc::str::from_boxed_utf8_unchecked(boxed) }
365    }
366    unsafe fn from_vec_unchecked(vec: Vec<Self::Item>) -> Self::Vec {
367        unsafe { String::from_utf8_unchecked(vec) }
368    }
369
370    type TryFromSliceError = core::str::Utf8Error;
371    fn try_from_slice(slice: &[Self::Item]) -> Result<&Self, Self::TryFromSliceError> {
372        core::str::from_utf8(slice)
373    }
374    fn try_from_slice_mut(slice: &mut [Self::Item]) -> Result<&mut Self, Self::TryFromSliceError> {
375        core::str::from_utf8_mut(slice)
376    }
377}
378
379pub(crate) fn check_char_boundary(s: &str, offset: usize) {
380    #[cold]
381    fn panic_not_a_char_boundary() -> ! {
382        panic!("not a char boundary")
383    }
384    unsafe { assume!(offset <= s.len()) };
385    if !s.is_char_boundary(offset) {
386        panic_not_a_char_boundary();
387    }
388}
389
390unsafe impl Subsliceable for str {
391    unsafe fn check_subslice(&self, start: usize, end: usize) {
392        check_char_boundary(self, start);
393        check_char_boundary(self, end);
394    }
395
396    unsafe fn check_split(&self, at: usize) {
397        check_char_boundary(self, at);
398    }
399}
400
401unsafe impl Concatenable for str {}
402
403#[cfg(feature = "serde")]
404impl Deserializable for str {
405    fn deserialize<'de, D: serde::Deserializer<'de>, V: serde::de::Visitor<'de>>(
406        deserializer: D,
407        visitor: V,
408    ) -> Result<V::Value, D::Error> {
409        deserializer.deserialize_string(visitor)
410    }
411    fn expecting(f: &mut core::fmt::Formatter) -> core::fmt::Result {
412        write!(f, "a string")
413    }
414    fn deserialize_from_bytes<E: serde::de::Error>(bytes: &[u8]) -> Result<&Self, E> {
415        core::str::from_utf8(bytes).map_err(E::custom)
416    }
417    fn deserialize_from_byte_buf<E: serde::de::Error>(bytes: Vec<u8>) -> Result<Self::Vec, E> {
418        String::from_utf8(bytes).map_err(E::custom)
419    }
420    fn deserialize_from_str<E: serde::de::Error>(s: &str) -> Result<&Self, E> {
421        Ok(s)
422    }
423    fn deserialize_from_string<E: serde::de::Error>(s: String) -> Result<Self::Vec, E> {
424        Ok(s)
425    }
426    fn try_deserialize_from_seq() -> bool {
427        false
428    }
429}
430
431/// A buffer that contains a slice.
432///
433/// Buffer needs to implement `Send`, as it may be dropped in another thread.
434pub trait Buffer<S: ?Sized>: Sized + Send + 'static {
435    /// Returns the buffer slice.
436    fn as_slice(&self) -> &S;
437    /// Returns if the buffer is unique, i.e. if this buffer is the only reference to its slice.
438    fn is_unique(&self) -> bool {
439        true
440    }
441}
442
443impl<S: Slice + ?Sized> Buffer<S> for &'static S {
444    fn as_slice(&self) -> &S {
445        self
446    }
447
448    fn is_unique(&self) -> bool {
449        false
450    }
451}
452
453impl<S: Slice + ?Sized> Buffer<S> for Box<S> {
454    fn as_slice(&self) -> &S {
455        self
456    }
457}
458
459impl<T: Send + 'static> Buffer<[T]> for Vec<T> {
460    fn as_slice(&self) -> &[T] {
461        self
462    }
463}
464
465impl Buffer<str> for String {
466    fn as_slice(&self) -> &str {
467        self
468    }
469}
470
471pub(crate) trait BufferExt<S: Slice + ?Sized>: Buffer<S> {
472    unsafe fn offset(&self, start: NonNull<S::Item>) -> usize {
473        unsafe { start.offset_from_unsigned(self.as_slice().as_ptr()) }
474    }
475
476    fn len(&self) -> usize {
477        self.as_slice().to_raw_parts().1
478    }
479}
480
481impl<S: Slice + ?Sized, B: Buffer<S>> BufferExt<S> for B {}
482
483/// A buffer that contains a mutable slice.
484///
485/// The buffer may be resizable, and the whole slice may have an uninitialized section.
486///
487/// # Safety
488///
489/// - [`as_mut_slice`] must return the same slice as [`Buffer::as_slice`]
490/// - The full buffer slice must have at least [`capacity`] maybe uninitialized items;
491///   [`as_mut_slice`] returns in fact the beginning of the full slice.
492/// - Accessing [`capacity`] must not invalidate the buffer slice.
493/// - If [`set_len`] returns `true`, then the length of [`as_mut_slice`] must have been
494///   updated accordingly.
495/// - If [`try_reserve`] returns successfully, then [`capacity`] must have been increased
496///   by at least `additional` items.
497/// - If the buffer implements [`BorrowMetadata`], then [`borrow_metadata`] must not
498///   invalidate the buffer slice.
499///
500/// [`as_mut_slice`]: Self::as_mut_slice
501/// [`capacity`]: Self::capacity
502/// [`set_len`]: Self::set_len
503/// [`try_reserve`]: Self::try_reserve
504/// [`borrow_metadata`]: BorrowMetadata::borrow_metadata
505pub unsafe trait BufferMut<S: ?Sized>: Buffer<S> {
506    /// Returns the mutable buffer slice.
507    fn as_mut_slice(&mut self) -> &mut S;
508    /// Returns the buffer capacity.
509    fn capacity(&self) -> usize;
510    /// Set the length of the buffer slice.
511    ///
512    /// Returns `false` if this operation is not supported, for example for fixed size buffers
513    /// like [`AsMutBuffer`].
514    ///
515    /// # Safety
516    ///
517    /// First `len` items of buffer slice must be initialized.
518    unsafe fn set_len(&mut self, len: usize) -> bool;
519    /// Tries reserving capacity for at least `additional` items.
520    fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>;
521}
522
523unsafe impl<T: Send + Sync + 'static> BufferMut<[T]> for Vec<T> {
524    fn as_mut_slice(&mut self) -> &mut [T] {
525        self
526    }
527
528    fn capacity(&self) -> usize {
529        self.capacity()
530    }
531
532    unsafe fn set_len(&mut self, len: usize) -> bool {
533        // SAFETY: same function contract
534        unsafe { self.set_len(len) };
535        true
536    }
537
538    fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
539        let requested = |len| (len as isize).checked_add(additional.try_into().ok()?);
540        match self.try_reserve(additional) {
541            Ok(()) => Ok(()),
542            Err(_) if requested(self.len()).is_none() => Err(TryReserveError::CapacityOverflow),
543            Err(_) => Err(TryReserveError::AllocError),
544        }
545    }
546}
547
548unsafe impl BufferMut<str> for String {
549    fn as_mut_slice(&mut self) -> &mut str {
550        self
551    }
552
553    fn capacity(&self) -> usize {
554        self.capacity()
555    }
556
557    unsafe fn set_len(&mut self, len: usize) -> bool {
558        // SAFETY: same function contract
559        unsafe { self.as_mut_vec().set_len(len) };
560        true
561    }
562
563    fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
564        BufferMut::try_reserve(unsafe { self.as_mut_vec() }, additional)
565    }
566}
567
568pub(crate) trait BufferMutExt<S: Slice + ?Sized>: BufferMut<S> {
569    unsafe fn realloc<T>(
570        &mut self,
571        additional: usize,
572        ptr: NonNull<T>,
573        layout: impl Fn(usize) -> Result<Layout, LayoutError>,
574    ) -> Result<(NonNull<T>, usize), TryReserveError> {
575        let required = self
576            .len()
577            .checked_add(additional)
578            .ok_or(TryReserveError::CapacityOverflow)?;
579        let new_capacity = max(self.capacity() * 2, required);
580        let cur_layout = unsafe { layout(self.capacity()).unwrap_unchecked() };
581        let new_layout = layout(new_capacity).map_err(|_| TryReserveError::CapacityOverflow)?;
582        let new_ptr =
583            NonNull::new(unsafe { realloc(ptr.as_ptr().cast(), cur_layout, new_layout.size()) })
584                .ok_or(TryReserveError::AllocError)?;
585        Ok((new_ptr.cast(), new_capacity))
586    }
587
588    unsafe fn shift_left(
589        &mut self,
590        offset: usize,
591        length: usize,
592        // do not use the pointer derived from slice as it is invalidated with the slice
593        start: impl Fn(&mut Self) -> NonNull<S::Item>,
594    ) -> bool {
595        assert_checked(!mem::needs_drop::<S::Item>());
596        let prev_len = self.len();
597        if length == prev_len {
598            return true;
599        }
600        if !unsafe { self.set_len(length) } {
601            return false;
602        }
603        let src = unsafe { start(self).add(offset) }.as_ptr();
604        let dst = start(self).as_ptr();
605        if offset == 0 {
606            return true;
607        } else if offset >= length {
608            unsafe { ptr::copy_nonoverlapping(src, dst, length) };
609        } else {
610            unsafe { ptr::copy(src, dst, length) };
611        }
612        true
613    }
614
615    unsafe fn try_reserve_impl(
616        &mut self,
617        offset: usize,
618        length: usize,
619        additional: usize,
620        allocate: bool,
621        // do not use the pointer derived from slice as it is invalidated with the slice
622        start: impl Fn(&mut Self) -> NonNull<S::Item>,
623    ) -> TryReserveResult<S::Item> {
624        let capacity = self.capacity();
625        if capacity - offset - length >= additional {
626            return (Ok(capacity - offset), unsafe { start(self).add(offset) });
627        }
628        if !mem::needs_drop::<S::Item>()
629            // conditions from `BytesMut::reserve_inner`
630            && self.capacity() - length >= additional
631            && offset >= length
632            && unsafe { self.shift_left(offset, length, &start) }
633        {
634            return (Ok(capacity), start(self));
635        }
636        if allocate && unsafe { self.set_len(offset + length) } {
637            let capacity = self
638                .try_reserve(additional)
639                .map(|_| self.capacity() - offset);
640            return (capacity, unsafe { start(self).add(offset) });
641        }
642        (Err(TryReserveError::Unsupported), unsafe {
643            start(self).add(offset)
644        })
645    }
646}
647
648impl<S: Slice + ?Sized, B: BufferMut<S>> BufferMutExt<S> for B {}
649
650#[cfg(feature = "raw-buffer")]
651/// A buffer that can be stored into a raw pointer.
652///
653/// The trait can be used when the actual buffer is already stored in an [`Arc`].
654///
655/// # Safety
656///
657/// - The slice returned by [`Buffer::as_slice`] must not be invalidated by
658///   [`into_raw`].
659/// - [`from_raw`] must be pure, i.e. `mem::forget(S::from_raw(ptr))` should not
660///   invalidate memory behind ptr.
661///
662/// [`Arc`]: alloc::sync::Arc
663/// [`into_raw`]: Self::into_raw
664/// [`from_raw`]: Self::from_raw
665pub unsafe trait RawBuffer<S: ?Sized>: Buffer<S> + Clone {
666    /// Converts the buffer into a raw pointer.
667    fn into_raw(self) -> *const ();
668    /// Converts back the buffer from a raw pointer.
669    ///
670    /// # Safety
671    ///
672    /// The pointer must be obtained by a call to [`RawBuffer::into_raw`].
673    unsafe fn from_raw(ptr: *const ()) -> Self;
674}
675
676/// A trait for borrowing metadata.
677pub trait BorrowMetadata: Sync {
678    /// The metadata borrowed.
679    type Metadata: Sync + 'static;
680    /// Borrow the metadata.
681    fn borrow_metadata(&self) -> &Self::Metadata;
682}
683
684mod private {
685    use core::{any::Any, ptr::NonNull};
686
687    #[allow(clippy::missing_safety_doc)]
688    pub unsafe trait DynBuffer {
689        type Buffer: Any;
690        type Metadata: Any;
691        fn get_metadata(&self) -> &Self::Metadata;
692        unsafe fn take_buffer(this: *mut Self, buffer: NonNull<()>);
693    }
694}
695
696unsafe impl<B: BorrowMetadata + Any> DynBuffer for B {
697    type Buffer = B;
698    type Metadata = B::Metadata;
699
700    fn get_metadata(&self) -> &Self::Metadata {
701        self.borrow_metadata()
702    }
703
704    unsafe fn take_buffer(this: *mut Self, buffer: NonNull<()>) {
705        unsafe { ptr::copy_nonoverlapping(this, buffer.as_ptr().cast(), 1) }
706    }
707}
708
709#[derive(Clone)]
710pub(crate) struct BufferWithMetadata<B, M> {
711    buffer: B,
712    metadata: M,
713}
714
715impl<B, M> BufferWithMetadata<B, M> {
716    pub(crate) fn new(buffer: B, metadata: M) -> Self {
717        Self { buffer, metadata }
718    }
719
720    pub(crate) fn buffer(self) -> B {
721        self.buffer
722    }
723
724    pub(crate) fn into_tuple(self) -> (B, M) {
725        (self.buffer, self.metadata)
726    }
727}
728
729impl<S: Slice + ?Sized, B: Buffer<S>, M: Send + Sync + 'static> Buffer<S>
730    for BufferWithMetadata<B, M>
731{
732    fn as_slice(&self) -> &S {
733        self.buffer.as_slice()
734    }
735
736    fn is_unique(&self) -> bool {
737        self.buffer.is_unique()
738    }
739}
740
741unsafe impl<S: Slice + ?Sized, B: BufferMut<S>, M: Send + Sync + 'static> BufferMut<S>
742    for BufferWithMetadata<B, M>
743{
744    fn as_mut_slice(&mut self) -> &mut S {
745        self.buffer.as_mut_slice()
746    }
747
748    fn capacity(&self) -> usize {
749        self.buffer.capacity()
750    }
751
752    unsafe fn set_len(&mut self, len: usize) -> bool {
753        unsafe { self.buffer.set_len(len) }
754    }
755
756    fn try_reserve(&mut self, _additional: usize) -> Result<(), TryReserveError> {
757        self.buffer.try_reserve(_additional)
758    }
759}
760
761#[cfg(feature = "raw-buffer")]
762unsafe impl<S: Slice + ?Sized, B: RawBuffer<S>> RawBuffer<S> for BufferWithMetadata<B, ()> {
763    fn into_raw(self) -> *const () {
764        self.buffer.into_raw()
765    }
766
767    unsafe fn from_raw(ptr: *const ()) -> Self {
768        Self::new(unsafe { B::from_raw(ptr) }, ())
769    }
770}
771
772unsafe impl<B: Any, M: Any> DynBuffer for BufferWithMetadata<B, M> {
773    type Buffer = B;
774    type Metadata = M;
775
776    fn get_metadata(&self) -> &Self::Metadata {
777        &self.metadata
778    }
779
780    unsafe fn take_buffer(this: *mut Self, buffer: NonNull<()>) {
781        unsafe { ptr::copy_nonoverlapping(addr_of!((*this).buffer), buffer.as_ptr().cast(), 1) }
782        unsafe { ptr::drop_in_place(addr_of_mut!((*this).metadata)) }
783    }
784}
785
786/// A wrapper around buffer implementing [`AsRef`].
787#[derive(Debug, Clone)]
788pub struct AsRefBuffer<B>(pub B);
789
790impl<B> Deref for AsRefBuffer<B> {
791    type Target = B;
792
793    fn deref(&self) -> &Self::Target {
794        &self.0
795    }
796}
797
798impl<B> DerefMut for AsRefBuffer<B> {
799    fn deref_mut(&mut self) -> &mut Self::Target {
800        &mut self.0
801    }
802}
803
804impl<S: ?Sized, B: AsRef<S> + Send + 'static> Buffer<S> for AsRefBuffer<B> {
805    fn as_slice(&self) -> &S {
806        self.0.as_ref()
807    }
808
809    fn is_unique(&self) -> bool {
810        false
811    }
812}
813
814impl<B: BorrowMetadata> BorrowMetadata for AsRefBuffer<B> {
815    type Metadata = B::Metadata;
816
817    fn borrow_metadata(&self) -> &Self::Metadata {
818        self.0.borrow_metadata()
819    }
820}
821
822/// A wrapper around buffer implementing [`AsMut`].
823///
824/// [`BufferMut`] implementation is not resizable, as it is based on a fixed-length slice.
825#[derive(Debug, Clone)]
826pub struct AsMutBuffer<B>(B);
827
828impl<B> AsMutBuffer<B> {
829    /// Creates a new `AsMutBuffer` from a given buffer.
830    ///
831    /// # SAFETY
832    ///
833    /// If buffer implements `AsMut<S>` and `AsRef<S>`, then both operations must return the same
834    /// slice. If `B` implements [`BorrowMetadata`], then [`borrow_metadata`] must not invalidate
835    /// the buffer slice.
836    ///
837    /// [`borrow_metadata`]: BorrowMetadata::borrow_metadata
838    pub unsafe fn new(buffer: B) -> Self {
839        Self(buffer)
840    }
841
842    /// Returns the inner buffer.
843    pub fn into_inner(self) -> B {
844        self.0
845    }
846}
847
848impl<B> Deref for AsMutBuffer<B> {
849    type Target = B;
850
851    fn deref(&self) -> &Self::Target {
852        &self.0
853    }
854}
855
856impl<B> DerefMut for AsMutBuffer<B> {
857    fn deref_mut(&mut self) -> &mut Self::Target {
858        &mut self.0
859    }
860}
861
862impl<S: ?Sized, B: AsRef<S> + Send + 'static> Buffer<S> for AsMutBuffer<B> {
863    fn as_slice(&self) -> &S {
864        self.0.as_ref()
865    }
866
867    fn is_unique(&self) -> bool {
868        false
869    }
870}
871
872/// SAFETY: Trait contract is upheld by `AsMutBuffer::new` contract.
873unsafe impl<S: Slice + ?Sized, B: AsRef<S> + AsMut<S> + Send + Sync + 'static> BufferMut<S>
874    for AsMutBuffer<B>
875{
876    fn as_mut_slice(&mut self) -> &mut S {
877        self.0.as_mut()
878    }
879
880    fn capacity(&self) -> usize {
881        self.0.as_ref().len()
882    }
883
884    unsafe fn set_len(&mut self, _len: usize) -> bool {
885        false
886    }
887
888    fn try_reserve(&mut self, _additional: usize) -> Result<(), TryReserveError> {
889        Err(TryReserveError::Unsupported)
890    }
891}
892
893impl<B: BorrowMetadata> BorrowMetadata for AsMutBuffer<B> {
894    type Metadata = B::Metadata;
895
896    fn borrow_metadata(&self) -> &Self::Metadata {
897        self.0.borrow_metadata()
898    }
899}
900
901#[cfg(any(not(feature = "portable-atomic"), feature = "portable-atomic-util"))]
902const _: () = {
903    #[cfg(not(feature = "portable-atomic"))]
904    use alloc::sync::Arc;
905
906    #[cfg(feature = "portable-atomic-util")]
907    use portable_atomic_util::Arc;
908
909    impl<B: BorrowMetadata + Send> BorrowMetadata for Arc<B> {
910        type Metadata = B::Metadata;
911        fn borrow_metadata(&self) -> &Self::Metadata {
912            self.as_ref().borrow_metadata()
913        }
914    }
915
916    impl<S: ?Sized, B: Buffer<S> + Sync> Buffer<S> for Arc<B> {
917        fn as_slice(&self) -> &S {
918            self.as_ref().as_slice()
919        }
920
921        fn is_unique(&self) -> bool {
922            // Arc doesn't expose an API to check uniqueness with shared reference
923            // See `Arc::is_unique`, it cannot be done by simply checking strong/weak counts
924            false
925        }
926    }
927
928    #[cfg(feature = "raw-buffer")]
929    unsafe impl<S: ?Sized, B: Buffer<S> + Sync> RawBuffer<S> for Arc<B> {
930        fn into_raw(self) -> *const () {
931            Arc::into_raw(self).cast()
932        }
933
934        unsafe fn from_raw(ptr: *const ()) -> Self {
935            unsafe { Arc::from_raw(ptr.cast()) }
936        }
937    }
938};