compio_buf/
iter.rs

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