compio_buf/
iter.rs

1use crate::*;
2
3/// The inner implementation of a [`OwnedIter`].
4///
5/// [`OwnedIter`]: IoVectoredBuf::OwnedIter
6pub trait OwnedIterator: IntoInner + Sized {
7    /// Get the next iterator.
8    ///
9    /// If current `Self` is the last one, return `Err(Self::Inner)` to give the
10    /// inner back.
11    fn next(self) -> Result<Self, Self::Inner>;
12}
13
14/// An owned iterator over an indexable container.
15pub struct IndexedIter<T> {
16    items: T,
17    nth: usize,
18}
19
20impl<T: Indexable> IndexedIter<T> {
21    /// Create a new [`IndexedIter`] from an indexable container. If the
22    /// container is empty, return the buffer back in `Err(T)`.
23    pub fn new(bufs: T) -> Result<Self, T> {
24        if bufs.index(0).is_none() {
25            Err(bufs)
26        } else {
27            Ok(Self {
28                items: bufs,
29                nth: 0,
30            })
31        }
32    }
33}
34
35unsafe impl<T> IoBuf for IndexedIter<T>
36where
37    T: Indexable + 'static,
38    T::Output: IoBuf,
39{
40    fn as_buf_ptr(&self) -> *const u8 {
41        self.items.index(self.nth).unwrap().as_buf_ptr()
42    }
43
44    fn buf_len(&self) -> usize {
45        self.items.index(self.nth).unwrap().buf_len()
46    }
47
48    fn buf_capacity(&self) -> usize {
49        self.items.index(self.nth).unwrap().buf_capacity()
50    }
51}
52
53impl<T> SetBufInit for IndexedIter<T>
54where
55    T: IndexableMut,
56    T::Output: IoBufMut,
57{
58    unsafe fn set_buf_init(&mut self, len: usize) {
59        self.items.index_mut(self.nth).unwrap().set_buf_init(len)
60    }
61}
62
63unsafe impl<T> IoBufMut for IndexedIter<T>
64where
65    T: IndexableMut + 'static,
66    T::Output: IoBufMut,
67{
68    fn as_buf_mut_ptr(&mut self) -> *mut u8 {
69        self.items.index_mut(self.nth).unwrap().as_buf_mut_ptr()
70    }
71}
72
73impl<T> IntoInner for IndexedIter<T> {
74    type Inner = T;
75
76    fn into_inner(self) -> Self::Inner {
77        self.items
78    }
79}
80
81impl<T: Indexable> OwnedIterator for IndexedIter<T> {
82    fn next(self) -> Result<Self, Self::Inner> {
83        if self.items.index(self.nth + 1).is_some() {
84            Ok(Self {
85                items: self.items,
86                nth: self.nth + 1,
87            })
88        } else {
89            Err(self.into_inner())
90        }
91    }
92}
93
94/// A trait for vectored buffers that could be indexed.
95pub trait Indexable {
96    /// Output item
97    type Output;
98
99    /// Get the item with specific index.
100    fn index(&self, n: usize) -> Option<&Self::Output>;
101}
102
103/// A trait for vectored buffers that could be mutably indexed.
104pub trait IndexableMut: Indexable {
105    /// Get the mutable item with specific index.
106    fn index_mut(&mut self, n: usize) -> Option<&mut Self::Output>;
107}
108
109impl<T> Indexable for &[T] {
110    type Output = T;
111
112    fn index(&self, n: usize) -> Option<&T> {
113        self.get(n)
114    }
115}
116
117impl<T> Indexable for &mut [T] {
118    type Output = T;
119
120    fn index(&self, n: usize) -> Option<&T> {
121        self.get(n)
122    }
123}
124
125impl<T: Indexable> Indexable for &T {
126    type Output = T::Output;
127
128    fn index(&self, n: usize) -> Option<&T::Output> {
129        (**self).index(n)
130    }
131}
132
133impl<T: Indexable> Indexable for &mut T {
134    type Output = T::Output;
135
136    fn index(&self, n: usize) -> Option<&T::Output> {
137        (**self).index(n)
138    }
139}
140
141impl<T, const N: usize> Indexable for [T; N] {
142    type Output = T;
143
144    fn index(&self, n: usize) -> Option<&T> {
145        self.get(n)
146    }
147}
148
149impl<T, #[cfg(feature = "allocator_api")] A: std::alloc::Allocator + 'static> Indexable
150    for t_alloc!(Vec, T, A)
151{
152    type Output = T;
153
154    fn index(&self, n: usize) -> Option<&T> {
155        self.get(n)
156    }
157}
158
159#[cfg(feature = "arrayvec")]
160impl<T, const N: usize> Indexable for arrayvec::ArrayVec<T, N> {
161    type Output = T;
162
163    fn index(&self, n: usize) -> Option<&T> {
164        self.get(n)
165    }
166}
167
168#[cfg(feature = "smallvec")]
169impl<T, const N: usize> Indexable for smallvec::SmallVec<[T; N]>
170where
171    [T; N]: smallvec::Array<Item = T>,
172{
173    type Output = T;
174
175    fn index(&self, n: usize) -> Option<&T> {
176        self.get(n)
177    }
178}
179
180impl<T> IndexableMut for &mut [T] {
181    fn index_mut(&mut self, n: usize) -> Option<&mut T> {
182        self.get_mut(n)
183    }
184}
185
186impl<T: IndexableMut> IndexableMut for &mut T {
187    fn index_mut(&mut self, n: usize) -> Option<&mut T::Output> {
188        (**self).index_mut(n)
189    }
190}
191
192impl<T, const N: usize> IndexableMut for [T; N] {
193    fn index_mut(&mut self, n: usize) -> Option<&mut T> {
194        self.get_mut(n)
195    }
196}
197
198impl<T, #[cfg(feature = "allocator_api")] A: std::alloc::Allocator + 'static> IndexableMut
199    for t_alloc!(Vec, T, A)
200{
201    fn index_mut(&mut self, n: usize) -> Option<&mut T> {
202        self.get_mut(n)
203    }
204}
205
206#[cfg(feature = "arrayvec")]
207impl<T, const N: usize> IndexableMut for arrayvec::ArrayVec<T, N> {
208    fn index_mut(&mut self, n: usize) -> Option<&mut T> {
209        self.get_mut(n)
210    }
211}
212
213#[cfg(feature = "smallvec")]
214impl<T, const N: usize> IndexableMut for smallvec::SmallVec<[T; N]>
215where
216    [T; N]: smallvec::Array<Item = T>,
217{
218    fn index_mut(&mut self, n: usize) -> Option<&mut T> {
219        self.get_mut(n)
220    }
221}