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}
122
123/// An owned view of a vectored buffer.
124pub struct VectoredSlice<T> {
125    buf: T,
126    begin: usize,
127}
128
129impl<T> VectoredSlice<T> {
130    pub(crate) fn new(buf: T, begin: usize) -> Self {
131        Self { buf, begin }
132    }
133
134    /// Offset in the underlying buffer at which this slice starts.
135    pub fn begin(&self) -> usize {
136        self.begin
137    }
138
139    /// Gets a reference to the underlying buffer.
140    ///
141    /// This method escapes the slice's view.
142    pub fn as_inner(&self) -> &T {
143        &self.buf
144    }
145
146    /// Gets a mutable reference to the underlying buffer.
147    ///
148    /// This method escapes the slice's view.
149    pub fn as_inner_mut(&mut self) -> &mut T {
150        &mut self.buf
151    }
152}
153
154impl<T: IoVectoredBuf> IoVectoredBuf for VectoredSlice<T> {
155    unsafe fn iter_io_buffer(&self) -> impl Iterator<Item = IoBuffer> {
156        let mut offset = self.begin;
157        self.buf.iter_io_buffer().filter_map(move |buf| {
158            let len = buf.len();
159            let sub = len.min(offset);
160            offset -= sub;
161            if len - sub > 0 {
162                Some(IoBuffer::new(
163                    buf.as_ptr().add(sub),
164                    len - sub,
165                    buf.capacity() - sub,
166                ))
167            } else {
168                None
169            }
170        })
171    }
172}
173
174impl<T> IntoInner for VectoredSlice<T> {
175    type Inner = T;
176
177    fn into_inner(self) -> Self::Inner {
178        self.buf
179    }
180}
181
182/// An owned view of a vectored buffer.
183pub struct VectoredSliceMut<T> {
184    buf: T,
185    begin: usize,
186}
187
188impl<T> VectoredSliceMut<T> {
189    pub(crate) fn new(buf: T, begin: usize) -> Self {
190        Self { buf, begin }
191    }
192
193    /// Offset in the underlying buffer at which this slice starts.
194    pub fn begin(&self) -> usize {
195        self.begin
196    }
197
198    /// Gets a reference to the underlying buffer.
199    ///
200    /// This method escapes the slice's view.
201    pub fn as_inner(&self) -> &T {
202        &self.buf
203    }
204
205    /// Gets a mutable reference to the underlying buffer.
206    ///
207    /// This method escapes the slice's view.
208    pub fn as_inner_mut(&mut self) -> &mut T {
209        &mut self.buf
210    }
211}
212
213impl<T: IoVectoredBuf> IoVectoredBuf for VectoredSliceMut<T> {
214    unsafe fn iter_io_buffer(&self) -> impl Iterator<Item = IoBuffer> {
215        let mut offset = self.begin;
216        self.buf.iter_io_buffer().filter_map(move |buf| {
217            let capacity = buf.capacity();
218            let sub = capacity.min(offset);
219            offset -= sub;
220            if capacity - sub > 0 {
221                let len = buf.len().saturating_sub(sub);
222                Some(IoBuffer::new(buf.as_ptr().add(sub), len, capacity - sub))
223            } else {
224                None
225            }
226        })
227    }
228}
229
230impl<T> IntoInner for VectoredSliceMut<T> {
231    type Inner = T;
232
233    fn into_inner(self) -> Self::Inner {
234        self.buf
235    }
236}
237
238impl<T: SetBufInit> SetBufInit for VectoredSliceMut<T> {
239    unsafe fn set_buf_init(&mut self, len: usize) {
240        self.buf.set_buf_init(self.begin + len);
241    }
242}
243
244impl<T: IoVectoredBufMut> IoVectoredBufMut for VectoredSliceMut<T> {}