compio_buf/
io_vec_buf.rs

1use std::ops::{Deref, DerefMut};
2
3use crate::{
4    t_alloc, IndexedIter, IoBuf, IoBufMut, IoSlice, IoSliceMut, OwnedIterator, SetBufInit,
5};
6
7/// A type that's either owned or borrowed. Like [`Cow`](std::rc::Cow) but
8/// without the requirement of [`ToOwned`].
9pub enum MaybeOwned<'a, T> {
10    /// Owned.
11    Owned(T),
12    /// Borrowed.
13    Borrowed(&'a T),
14}
15
16impl<T> Deref for MaybeOwned<'_, T> {
17    type Target = T;
18
19    fn deref(&self) -> &Self::Target {
20        match self {
21            MaybeOwned::Owned(t) => t,
22            MaybeOwned::Borrowed(t) => t,
23        }
24    }
25}
26
27/// A type that's either owned or mutably borrowed .
28pub enum MaybeOwnedMut<'a, T> {
29    /// Owned.
30    Owned(T),
31    /// Mutably borrowed.
32    Borrowed(&'a mut T),
33}
34
35impl<T> Deref for MaybeOwnedMut<'_, T> {
36    type Target = T;
37
38    fn deref(&self) -> &Self::Target {
39        match self {
40            MaybeOwnedMut::Owned(t) => t,
41            MaybeOwnedMut::Borrowed(t) => t,
42        }
43    }
44}
45
46impl<T> DerefMut for MaybeOwnedMut<'_, T> {
47    fn deref_mut(&mut self) -> &mut Self::Target {
48        match self {
49            MaybeOwnedMut::Owned(t) => t,
50            MaybeOwnedMut::Borrowed(t) => t,
51        }
52    }
53}
54
55/// A trait for vectored buffers.
56pub trait IoVectoredBuf: 'static {
57    /// The buffer.
58    type Buf: IoBuf;
59
60    /// The owned iterator that wraps `Self`.
61    type OwnedIter: OwnedIterator<Inner = Self> + IoBuf;
62
63    /// Collected [`IoSlice`]s of the buffers.
64    ///
65    /// # Safety
66    ///
67    /// The return slice will not live longer than self.
68    /// It is static to provide convenience from writing self-referenced
69    /// structure.
70    unsafe fn io_slices(&self) -> Vec<IoSlice> {
71        self.iter_buf().map(|buf| buf.as_io_slice()).collect()
72    }
73
74    /// An iterator over the buffers that's either owned or borrowed with
75    /// [`MaybeOwned`].
76    fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, Self::Buf>>;
77
78    /// Wrap self into an owned iterator.
79    fn owned_iter(self) -> Result<Self::OwnedIter, Self>
80    where
81        Self: Sized;
82}
83
84impl<T: IoBuf> IoVectoredBuf for &'static [T] {
85    type Buf = T;
86    type OwnedIter = IndexedIter<Self>;
87
88    fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
89        self.iter().map(MaybeOwned::Borrowed)
90    }
91
92    fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
93        IndexedIter::new(self)
94    }
95}
96
97impl<T: IoBuf> IoVectoredBuf for &'static mut [T] {
98    type Buf = T;
99    type OwnedIter = IndexedIter<Self>;
100
101    fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
102        self.iter().map(MaybeOwned::Borrowed)
103    }
104
105    fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
106        IndexedIter::new(self)
107    }
108}
109
110impl<T: IoBuf, const N: usize> IoVectoredBuf for [T; N] {
111    type Buf = T;
112    type OwnedIter = IndexedIter<Self>;
113
114    fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
115        self.iter().map(MaybeOwned::Borrowed)
116    }
117
118    fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
119        IndexedIter::new(self)
120    }
121}
122
123impl<T: IoBuf, #[cfg(feature = "allocator_api")] A: std::alloc::Allocator + 'static> IoVectoredBuf
124    for t_alloc!(Vec, T, A)
125{
126    type Buf = T;
127    type OwnedIter = IndexedIter<Self>;
128
129    fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
130        self.iter().map(MaybeOwned::Borrowed)
131    }
132
133    fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
134        IndexedIter::new(self)
135    }
136}
137
138#[cfg(feature = "arrayvec")]
139impl<T: IoBuf, const N: usize> IoVectoredBuf for arrayvec::ArrayVec<T, N> {
140    type Buf = T;
141    type OwnedIter = IndexedIter<Self>;
142
143    fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
144        self.iter().map(MaybeOwned::Borrowed)
145    }
146
147    fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
148        IndexedIter::new(self)
149    }
150}
151
152#[cfg(feature = "smallvec")]
153impl<T: IoBuf, const N: usize> IoVectoredBuf for smallvec::SmallVec<[T; N]>
154where
155    [T; N]: smallvec::Array<Item = T>,
156{
157    type Buf = T;
158    type OwnedIter = IndexedIter<Self>;
159
160    fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
161        self.iter().map(MaybeOwned::Borrowed)
162    }
163
164    fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
165        IndexedIter::new(self)
166    }
167}
168
169/// A trait for mutable vectored buffers.
170pub trait IoVectoredBufMut: IoVectoredBuf<Buf: IoBufMut, OwnedIter: IoBufMut> + SetBufInit {
171    /// An iterator for the [`IoSliceMut`]s of the buffers.
172    ///
173    /// # Safety
174    ///
175    /// The return slice will not live longer than self.
176    /// It is static to provide convenience from writing self-referenced
177    /// structure.
178    unsafe fn io_slices_mut(&mut self) -> Vec<IoSliceMut> {
179        self.iter_buf_mut()
180            .map(|mut buf| buf.as_io_slice_mut())
181            .collect()
182    }
183
184    /// An iterator over the buffers that's either owned or mutably borrowed
185    /// with [`MaybeOwnedMut`].
186    fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>>;
187}
188
189impl<T: IoBufMut> IoVectoredBufMut for &'static mut [T] {
190    fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
191        self.iter_mut().map(MaybeOwnedMut::Borrowed)
192    }
193}
194
195impl<T: IoBufMut, const N: usize> IoVectoredBufMut for [T; N] {
196    fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
197        self.iter_mut().map(MaybeOwnedMut::Borrowed)
198    }
199}
200
201impl<T: IoBufMut, #[cfg(feature = "allocator_api")] A: std::alloc::Allocator + 'static>
202    IoVectoredBufMut for t_alloc!(Vec, T, A)
203{
204    fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
205        self.iter_mut().map(MaybeOwnedMut::Borrowed)
206    }
207}
208
209#[cfg(feature = "arrayvec")]
210impl<T: IoBufMut, const N: usize> IoVectoredBufMut for arrayvec::ArrayVec<T, N> {
211    fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
212        self.iter_mut().map(MaybeOwnedMut::Borrowed)
213    }
214}
215
216#[cfg(feature = "smallvec")]
217impl<T: IoBufMut, const N: usize> IoVectoredBufMut for smallvec::SmallVec<[T; N]>
218where
219    [T; N]: smallvec::Array<Item = T>,
220{
221    fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
222        self.iter_mut().map(MaybeOwnedMut::Borrowed)
223    }
224}