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/// ```
25pub struct Slice<T> {
26    buffer: T,
27    begin: usize,
28    end: usize,
29}
30
31impl<T> Slice<T> {
32    pub(crate) fn new(buffer: T, begin: usize, end: usize) -> Self {
33        Self { buffer, begin, end }
34    }
35
36    /// Offset in the underlying buffer at which this slice starts.
37    pub fn begin(&self) -> usize {
38        self.begin
39    }
40
41    /// Offset in the underlying buffer at which this slice ends.
42    pub fn end(&self) -> usize {
43        self.end
44    }
45
46    /// Gets a reference to the underlying buffer.
47    ///
48    /// This method escapes the slice's view.
49    pub fn as_inner(&self) -> &T {
50        &self.buffer
51    }
52
53    /// Gets a mutable reference to the underlying buffer.
54    ///
55    /// This method escapes the slice's view.
56    pub fn as_inner_mut(&mut self) -> &mut T {
57        &mut self.buffer
58    }
59}
60
61fn slice_mut<T: IoBufMut>(buffer: &mut T) -> &mut [u8] {
62    unsafe { std::slice::from_raw_parts_mut(buffer.as_buf_mut_ptr(), (*buffer).buf_len()) }
63}
64
65impl<T: IoBuf> Deref for Slice<T> {
66    type Target = [u8];
67
68    fn deref(&self) -> &Self::Target {
69        let bytes = self.buffer.as_slice();
70        let end = self.end.min(bytes.len());
71        &bytes[self.begin..end]
72    }
73}
74
75impl<T: IoBufMut> DerefMut for Slice<T> {
76    fn deref_mut(&mut self) -> &mut Self::Target {
77        let bytes = slice_mut(&mut self.buffer);
78        let end = self.end.min(bytes.len());
79        &mut bytes[self.begin..end]
80    }
81}
82
83unsafe impl<T: IoBuf> IoBuf for Slice<T> {
84    fn as_buf_ptr(&self) -> *const u8 {
85        self.buffer.as_slice()[self.begin..].as_ptr()
86    }
87
88    fn buf_len(&self) -> usize {
89        self.deref().len()
90    }
91
92    fn buf_capacity(&self) -> usize {
93        self.end - self.begin
94    }
95}
96
97unsafe impl<T: IoBufMut> IoBufMut for Slice<T> {
98    fn as_buf_mut_ptr(&mut self) -> *mut u8 {
99        slice_mut(&mut self.buffer)[self.begin..].as_mut_ptr()
100    }
101}
102
103impl<T: SetBufInit> SetBufInit for Slice<T> {
104    unsafe fn set_buf_init(&mut self, len: usize) {
105        self.buffer.set_buf_init(self.begin + len)
106    }
107}
108
109impl<T> IntoInner for Slice<T> {
110    type Inner = T;
111
112    fn into_inner(self) -> Self::Inner {
113        self.buffer
114    }
115}