engine/collections/ring_buffer/slice.rs
1// SPDX-FileCopyrightText: 2025 Jens Pitkänen <jens.pitkanen@helsinki.fi>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5use core::ops::{Deref, DerefMut};
6
7use platform::Box;
8
9use super::RingAllocationMetadata;
10
11/// Owned slice of a [`RingBuffer`](super::RingBuffer).
12/// [`RingBuffer::free`](super::RingBuffer::free) instead of [`drop`]!
13#[derive(Debug)]
14pub struct RingSlice<T: 'static> {
15 pub(super) slice: Box<[T]>,
16 pub(super) metadata: RingAllocationMetadata,
17}
18
19impl<T> RingSlice<T> {
20 /// Splits this [`RingSlice`] into its raw parts. Can be combined back with
21 /// [`RingSlice::from_parts`].
22 ///
23 /// Useful for cases where some API is expecting a [`Box`] and a deref isn't
24 /// enough.
25 pub fn into_parts(self) -> (Box<[T]>, RingAllocationMetadata) {
26 (self.slice, self.metadata)
27 }
28
29 /// ### Safety
30 ///
31 /// The parts passed in must be a pair returned by an earlier
32 /// [`RingSlice::into_parts`] call. Mixing up metadatas and slices is not
33 /// allowed, because it will result in aliased mutable borrows, so
34 /// definitely very Undefined-Behavior.
35 pub unsafe fn from_parts(slice: Box<[T]>, metadata: RingAllocationMetadata) -> RingSlice<T> {
36 RingSlice { slice, metadata }
37 }
38}
39
40impl<T> Deref for RingSlice<T> {
41 type Target = [T];
42 fn deref(&self) -> &Self::Target {
43 &self.slice
44 }
45}
46
47impl<T> DerefMut for RingSlice<T> {
48 fn deref_mut(&mut self) -> &mut Self::Target {
49 &mut self.slice
50 }
51}