1use std::ops::{Deref, DerefMut};
2
3use crate::{
4 t_alloc, IndexedIter, IoBuf, IoBufMut, IoSlice, IoSliceMut, OwnedIterator, SetBufInit,
5};
6
7pub enum MaybeOwned<'a, T> {
10 Owned(T),
12 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
27pub enum MaybeOwnedMut<'a, T> {
29 Owned(T),
31 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
55pub trait IoVectoredBuf: 'static {
57 type Buf: IoBuf;
59
60 type OwnedIter: OwnedIterator<Inner = Self> + IoBuf;
62
63 unsafe fn io_slices(&self) -> Vec<IoSlice> {
71 self.iter_buf().map(|buf| buf.as_io_slice()).collect()
72 }
73
74 fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, Self::Buf>>;
77
78 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
169pub trait IoVectoredBufMut: IoVectoredBuf<Buf: IoBufMut, OwnedIter: IoBufMut> + SetBufInit {
171 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 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}