oracle/sql_type/
collection.rs1use crate::sql_type::{Collection, FromSql};
2use crate::ErrorKind;
3use crate::Result;
4use std::iter::FusedIterator;
5use std::marker::PhantomData;
6
7#[derive(Clone, Debug)]
8enum State {
9 Begin,
10 Current(i32),
11 End,
12}
13
14impl State {
15 fn next(&self, coll: &Collection) -> Result<State> {
16 let index_result = match self {
17 State::Begin => coll.first_index(),
18 State::Current(index) => coll.next_index(*index),
19 State::End => return Ok(State::End),
20 };
21 match index_result {
22 Ok(index) => Ok(State::Current(index)),
23 Err(err) if err.kind() == ErrorKind::NoDataFound => Ok(State::End),
24 Err(err) => Err(err),
25 }
26 }
27
28 fn next_back(&self, coll: &Collection) -> Result<State> {
29 let index_result = match self {
30 State::Begin => return Ok(State::Begin),
31 State::Current(index) => coll.prev_index(*index),
32 State::End => coll.last_index(),
33 };
34 match index_result {
35 Ok(index) => Ok(State::Current(index)),
36 Err(err) if err.kind() == ErrorKind::NoDataFound => Ok(State::Begin),
37 Err(err) => Err(err),
38 }
39 }
40}
41
42#[derive(Clone, Debug)]
46pub struct Iter<'a, T: FromSql> {
47 coll: &'a Collection,
48 state: State,
49 phantom: PhantomData<T>,
50}
51
52impl<T: FromSql> Iter<'_, T> {
53 fn try_next(&mut self) -> Result<Option<(i32, T)>> {
54 let next_state = self.state.next(self.coll)?;
55 let result = if let State::Current(index) = next_state {
56 Some((index, self.coll.get(index)?))
57 } else {
58 None
59 };
60 self.state = next_state;
61 Ok(result)
62 }
63
64 fn try_next_back(&mut self) -> Result<Option<(i32, T)>> {
65 let next_state = self.state.next_back(self.coll)?;
66 let result = if let State::Current(index) = next_state {
67 Some((index, self.coll.get(index)?))
68 } else {
69 None
70 };
71 self.state = next_state;
72 Ok(result)
73 }
74}
75
76impl<T: FromSql> Iter<'_, T> {
77 pub(crate) fn new(coll: &Collection) -> Iter<T> {
78 Iter {
79 coll,
80 state: State::Begin,
81 phantom: PhantomData,
82 }
83 }
84}
85
86impl<T> Iterator for Iter<'_, T>
87where
88 T: FromSql,
89{
90 type Item = Result<(i32, T)>;
91 fn next(&mut self) -> Option<Result<(i32, T)>> {
92 self.try_next().transpose()
93 }
94}
95
96impl<T> DoubleEndedIterator for Iter<'_, T>
97where
98 T: FromSql,
99{
100 fn next_back(&mut self) -> Option<Result<(i32, T)>> {
101 self.try_next_back().transpose()
102 }
103}
104
105impl<T: FromSql> FusedIterator for Iter<'_, T> {}
106
107#[derive(Clone, Debug)]
111pub struct Values<'a, T: FromSql> {
112 coll: &'a Collection,
113 state: State,
114 phantom: PhantomData<T>,
115}
116
117impl<T: FromSql> Values<'_, T> {
118 fn try_next(&mut self) -> Result<Option<T>> {
119 let next_state = self.state.next(self.coll)?;
120 let result = if let State::Current(index) = next_state {
121 Some(self.coll.get(index)?)
122 } else {
123 None
124 };
125 self.state = next_state;
126 Ok(result)
127 }
128
129 fn try_next_back(&mut self) -> Result<Option<T>> {
130 let next_state = self.state.next_back(self.coll)?;
131 let result = if let State::Current(index) = next_state {
132 Some(self.coll.get(index)?)
133 } else {
134 None
135 };
136 self.state = next_state;
137 Ok(result)
138 }
139}
140
141impl<T: FromSql> Values<'_, T> {
142 pub(crate) fn new(coll: &Collection) -> Values<T> {
143 Values {
144 coll,
145 state: State::Begin,
146 phantom: PhantomData,
147 }
148 }
149}
150
151impl<T> Iterator for Values<'_, T>
152where
153 T: FromSql,
154{
155 type Item = Result<T>;
156 fn next(&mut self) -> Option<Result<T>> {
157 self.try_next().transpose()
158 }
159}
160
161impl<T> DoubleEndedIterator for Values<'_, T>
162where
163 T: FromSql,
164{
165 fn next_back(&mut self) -> Option<Result<T>> {
166 self.try_next_back().transpose()
167 }
168}
169
170impl<T: FromSql> FusedIterator for Values<'_, T> {}
171
172#[derive(Clone, Debug)]
176pub struct Indices<'a> {
177 coll: &'a Collection,
178 state: State,
179}
180
181impl Indices<'_> {
182 pub(crate) fn new(coll: &Collection) -> Indices {
183 Indices {
184 coll,
185 state: State::Begin,
186 }
187 }
188
189 fn try_next(&mut self) -> Result<Option<i32>> {
190 self.state = self.state.next(self.coll)?;
191 Ok(if let State::Current(index) = self.state {
192 Some(index)
193 } else {
194 None
195 })
196 }
197
198 fn try_next_back(&mut self) -> Result<Option<i32>> {
199 self.state = self.state.next_back(self.coll)?;
200 Ok(if let State::Current(index) = self.state {
201 Some(index)
202 } else {
203 None
204 })
205 }
206}
207
208impl Iterator for Indices<'_> {
209 type Item = Result<i32>;
210 fn next(&mut self) -> Option<Result<i32>> {
211 self.try_next().transpose()
212 }
213}
214
215impl DoubleEndedIterator for Indices<'_> {
216 fn next_back(&mut self) -> Option<Result<i32>> {
217 self.try_next_back().transpose()
218 }
219}
220
221impl FusedIterator for Indices<'_> {}