Skip to main content

base_scheduler/
buffer_slice.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use crate::{IoBuf, IoBufMut};
5use std::ops::{Bound, Range, RangeBounds};
6
7/// An owned view into initialized storage. Dropping it drops its owner; `into_inner` recovers the complete buffer after an operation returns it.
8#[derive(Debug, Clone)]
9pub struct BufferSlice<B> {
10    buffer: B,
11    range: Range<usize>,
12}
13
14impl<B: IoBuf> BufferSlice<B> {
15    pub(crate) fn new(buffer: B, range: impl RangeBounds<usize>) -> Self {
16        let start = match range.start_bound() {
17            Bound::Included(&start) => start,
18            Bound::Excluded(&start) => start.checked_add(1).expect("buffer range start overflow"),
19            Bound::Unbounded => 0,
20        };
21        let end = match range.end_bound() {
22            Bound::Included(&end) => end.checked_add(1).expect("buffer range end overflow"),
23            Bound::Excluded(&end) => end,
24            Bound::Unbounded => buffer.as_ref().len(),
25        };
26        assert!(
27            start <= end && end <= buffer.as_ref().len(),
28            "buffer range out of bounds"
29        );
30        Self {
31            buffer,
32            range: start..end,
33        }
34    }
35
36    /// Discard the view's range and return the complete underlying buffer.
37    pub fn into_inner(self) -> B {
38        self.buffer
39    }
40}
41
42impl<B: IoBuf> AsRef<[u8]> for BufferSlice<B> {
43    fn as_ref(&self) -> &[u8] {
44        &self.buffer.as_ref()[self.range.clone()]
45    }
46}
47
48impl<B: IoBufMut> AsMut<[u8]> for BufferSlice<B> {
49    fn as_mut(&mut self) -> &mut [u8] {
50        &mut self.buffer.as_mut()[self.range.clone()]
51    }
52}
53
54// SAFETY: The view retains its owner and always exposes the same validated subrange. Moving the view does not move or resize the backing allocation.
55unsafe impl<B: IoBuf> IoBuf for BufferSlice<B> {}
56unsafe impl<B: IoBufMut> IoBufMut for BufferSlice<B> {}