tokio_io_utility/
init_maybeuninit_io_slice.rs

1use std::{
2    io::IoSlice,
3    iter::{IntoIterator, Iterator},
4    mem::MaybeUninit,
5};
6
7pub fn init_maybeuninit_io_slices_mut<'a, 'io_slice, Iterable>(
8    uninit_io_slices: &'a mut [MaybeUninit<IoSlice<'io_slice>>],
9    iterable: Iterable,
10) -> &'a mut [IoSlice<'io_slice>]
11where
12    Iterable: IntoIterator<Item = IoSlice<'io_slice>>,
13{
14    fn inner<'a, 'io_slice>(
15        uninit_io_slices: &'a mut [MaybeUninit<IoSlice<'io_slice>>],
16        iterable: &mut dyn Iterator<Item = IoSlice<'io_slice>>,
17    ) -> &'a mut [IoSlice<'io_slice>] {
18        let mut cnt = 0;
19
20        uninit_io_slices
21            .iter_mut()
22            .zip(iterable)
23            .for_each(|(uninit_io_slice, io_slice)| {
24                uninit_io_slice.write(io_slice);
25                cnt += 1;
26            });
27
28        // Safety:
29        //
30        //  - uninit_io_slices[..cnt] is initialized using iterable.
31        //  - MaybeUninit is a transparent type
32        unsafe { &mut *((&mut uninit_io_slices[..cnt]) as *mut _ as *mut [IoSlice<'io_slice>]) }
33    }
34
35    inner(uninit_io_slices, &mut iterable.into_iter())
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use crate::IoSliceExt;
42
43    #[test]
44    fn test() {
45        let mut uninit_io_slices = [MaybeUninit::<IoSlice<'_>>::uninit(); 5];
46        let io_slices = [
47            IoSlice::new(b"1023x"),
48            IoSlice::new(b"1qwe"),
49            IoSlice::new(b"''weqdq"),
50            IoSlice::new(b"jiasodjx"),
51            IoSlice::new(b"aqw34f"),
52        ];
53        assert_io_slices_eq(
54            init_maybeuninit_io_slices_mut(&mut uninit_io_slices, io_slices),
55            &io_slices,
56        );
57    }
58
59    fn assert_io_slices_eq(x: &[IoSlice<'_>], y: &[IoSlice<'_>]) {
60        assert_eq!(x.len(), y.len());
61
62        let x: Vec<&[u8]> = x.iter().copied().map(IoSliceExt::into_inner).collect();
63        let y: Vec<&[u8]> = y.iter().copied().map(IoSliceExt::into_inner).collect();
64
65        assert_eq!(x, y);
66    }
67}