completeio/buf/
buf_wrapper.rs

1use std::{
2    io::{IoSlice, IoSliceMut},
3    mem::MaybeUninit,
4};
5
6use crate::buf::*;
7
8/// Holds an immutable IO buffer and IoSlice.
9#[derive(Debug)]
10pub struct BufWrapper<'arena, T: 'arena> {
11    buffer: T,
12    io_slice: [IoSlice<'arena>; 1],
13}
14
15impl<'arena, T: IoBuf<'arena>> From<T> for BufWrapper<'arena, T> {
16    fn from(buffer: T) -> Self {
17        // SAFETY: buffer Unpin and could be self referenced
18        let io_slice = [IoSlice::new(unsafe {
19            &*(buffer.as_slice() as *const [u8])
20        })];
21        Self { buffer, io_slice }
22    }
23}
24
25impl<T> IntoInner for BufWrapper<'_, T> {
26    type Inner = T;
27
28    fn into_inner(self) -> Self::Inner {
29        self.buffer
30    }
31}
32
33/// Holds an mutable IO buffer and IoSliceMut.
34#[derive(Debug)]
35pub struct BufWrapperMut<'arena, T: 'arena> {
36    buffer: T,
37    io_slice_mut: [IoSliceMut<'arena>; 1],
38}
39
40impl<T> IntoInner for BufWrapperMut<'_, T> {
41    type Inner = T;
42
43    fn into_inner(self) -> Self::Inner {
44        self.buffer
45    }
46}
47
48impl<'arena, T: IoBufMut<'arena>> From<T> for BufWrapperMut<'arena, T> {
49    fn from(mut buffer: T) -> Self {
50        // SAFETY: buffer Unpin and could be self referenced
51        let io_slice_mut = [IoSliceMut::new(unsafe {
52            slice_assume_init_mut::<'arena>(buffer.as_uninit_slice() as *mut [MaybeUninit<u8>])
53        })];
54        Self {
55            buffer,
56            io_slice_mut,
57        }
58    }
59}
60
61unsafe fn slice_assume_init_mut<'arena>(slice: *mut [MaybeUninit<u8>]) -> &'arena mut [u8] {
62    unsafe { &mut *(slice as *mut [u8]) }
63}
64
65impl<'arena, T: IoBuf<'arena>> AsIoSlices<'arena> for BufWrapper<'arena, T> {
66    unsafe fn as_io_slices(&self) -> &[IoSlice<'arena>] {
67        &self.io_slice
68    }
69}
70
71impl<'arena, T: IoBufMut<'arena>> AsIoSlicesMut<'arena> for BufWrapperMut<'arena, T> {
72    unsafe fn as_io_slices_mut(&mut self) -> &mut [IoSliceMut<'arena>] {
73        &mut self.io_slice_mut
74    }
75
76    fn set_init(&mut self, len: usize) {
77        self.buffer.set_buf_init(len)
78    }
79}
80
81/// Fixed slice of IO buffers.
82#[derive(Debug)]
83pub struct VectoredBufWrapper<'arena, T: 'arena> {
84    buffers: Box<[T]>,
85    io_slices: Box<[IoSlice<'arena>]>,
86    io_slices_mut: Box<[IoSliceMut<'arena>]>,
87}
88
89impl<T> IntoInner for VectoredBufWrapper<'_, T> {
90    type Inner = Box<[T]>;
91
92    fn into_inner(self) -> Self::Inner {
93        self.buffers
94    }
95}
96
97impl<'arena, T: IoBufMut<'arena>> From<Box<[T]>> for VectoredBufWrapper<'arena, T> {
98    fn from(mut buffers: Box<[T]>) -> Self {
99        let io_slices: Box<[IoSlice<'arena>]> = unsafe {
100            buffers
101                .iter()
102                .map(|buf| IoSlice::new(&*(buf.as_slice() as *const _ as *const _)))
103                .collect::<Vec<_>>()
104                .into_boxed_slice()
105        };
106        let io_slices_mut: Box<[IoSliceMut<'arena>]> = unsafe {
107            buffers
108                .iter_mut()
109                .map(|buf| IoSliceMut::new(&mut *(buf.as_uninit_slice() as *mut _ as *mut _)))
110                .collect::<Vec<_>>()
111                .into_boxed_slice()
112        };
113        Self {
114            buffers,
115            io_slices,
116            io_slices_mut,
117        }
118    }
119}
120
121impl<'arena, T: IoBuf<'arena>> AsIoSlices<'arena> for VectoredBufWrapper<'arena, T> {
122    unsafe fn as_io_slices(&self) -> &[IoSlice<'_>] {
123        &self.io_slices
124    }
125}
126
127impl<'arena, T: IoBufMut<'arena>> AsIoSlicesMut<'arena> for VectoredBufWrapper<'arena, T> {
128    unsafe fn as_io_slices_mut(&mut self) -> &mut [IoSliceMut<'arena>] {
129        &mut self.io_slices_mut
130    }
131
132    fn set_init(&mut self, mut len: usize) {
133        for buf in self.buffers.iter_mut() {
134            let capacity = buf.buf_capacity();
135            if len >= capacity {
136                buf.set_buf_init(capacity);
137                len -= capacity;
138            } else {
139                buf.set_buf_init(len);
140                len = 0;
141            }
142        }
143    }
144}