compio_buf/
slice.rs

1use std::ops::{Deref, DerefMut};
2
3use crate::*;
4
5/// An owned view into a contiguous sequence of bytes.
6///
7/// This is similar to Rust slices (`&buf[..]`) but owns the underlying buffer.
8/// This type is useful for performing io-uring read and write operations using
9/// a subset of a buffer.
10///
11/// Slices are created using [`IoBuf::slice`].
12///
13/// # Examples
14///
15/// Creating a slice
16///
17/// ```
18/// use compio_buf::IoBuf;
19///
20/// let buf = b"hello world";
21/// let slice = buf.slice(..5);
22///
23/// assert_eq!(&slice[..], b"hello");
24/// ```
25#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
26pub struct Slice<T> {
27    buffer: T,
28    begin: usize,
29    end: usize,
30}
31
32impl<T> Slice<T> {
33    pub(crate) fn new(buffer: T, begin: usize, end: usize) -> Self {
34        Self { buffer, begin, end }
35    }
36
37    /// Offset in the underlying buffer at which this slice starts.
38    pub fn begin(&self) -> usize {
39        self.begin
40    }
41
42    /// Offset in the underlying buffer at which this slice ends.
43    pub fn end(&self) -> usize {
44        self.end
45    }
46
47    pub(crate) fn set_range(&mut self, begin: usize, end: usize) {
48        self.begin = begin;
49        self.end = end;
50    }
51
52    /// Gets a reference to the underlying buffer.
53    ///
54    /// This method escapes the slice's view.
55    pub fn as_inner(&self) -> &T {
56        &self.buffer
57    }
58
59    /// Gets a mutable reference to the underlying buffer.
60    ///
61    /// This method escapes the slice's view.
62    pub fn as_inner_mut(&mut self) -> &mut T {
63        &mut self.buffer
64    }
65}
66
67fn slice_mut<T: IoBufMut>(buffer: &mut T) -> &mut [u8] {
68    unsafe { std::slice::from_raw_parts_mut(buffer.as_buf_mut_ptr(), (*buffer).buf_len()) }
69}
70
71impl<T: IoBuf> Deref for Slice<T> {
72    type Target = [u8];
73
74    fn deref(&self) -> &Self::Target {
75        let bytes = self.buffer.as_slice();
76        let end = self.end.min(bytes.len());
77        &bytes[self.begin..end]
78    }
79}
80
81impl<T: IoBufMut> DerefMut for Slice<T> {
82    fn deref_mut(&mut self) -> &mut Self::Target {
83        let bytes = slice_mut(&mut self.buffer);
84        let end = self.end.min(bytes.len());
85        &mut bytes[self.begin..end]
86    }
87}
88
89unsafe impl<T: IoBuf> IoBuf for Slice<T> {
90    fn as_buf_ptr(&self) -> *const u8 {
91        self.buffer.as_slice()[self.begin..].as_ptr()
92    }
93
94    fn buf_len(&self) -> usize {
95        self.deref().len()
96    }
97
98    fn buf_capacity(&self) -> usize {
99        self.end - self.begin
100    }
101}
102
103unsafe impl<T: IoBufMut> IoBufMut for Slice<T> {
104    fn as_buf_mut_ptr(&mut self) -> *mut u8 {
105        slice_mut(&mut self.buffer)[self.begin..].as_mut_ptr()
106    }
107}
108
109impl<T: SetBufInit> SetBufInit for Slice<T> {
110    unsafe fn set_buf_init(&mut self, len: usize) {
111        self.buffer.set_buf_init(self.begin + len)
112    }
113}
114
115impl<T> IntoInner for Slice<T> {
116    type Inner = T;
117
118    fn into_inner(self) -> Self::Inner {
119        self.buffer
120    }
121}