1use crate::data::*;
2use std::fmt;
3use std::ops::Deref;
4use std::sync::Arc;
5
6#[derive(PartialEq, Eq)]
8pub struct Results {
9 results: Vec<Vec<DataType>>,
10 columns: Arc<[String]>,
11}
12
13impl Results {
14 #[doc(hidden)]
17 pub fn new(results: Vec<Vec<DataType>>, columns: Arc<[String]>) -> Self {
18 Self { results, columns }
19 }
20
21 pub fn iter(&self) -> ResultIter<'_> {
23 self.into_iter()
24 }
25}
26
27impl Into<Vec<Vec<DataType>>> for Results {
28 fn into(self) -> Vec<Vec<DataType>> {
29 self.results
30 }
31}
32
33impl PartialEq<[Vec<DataType>]> for Results {
34 fn eq(&self, other: &[Vec<DataType>]) -> bool {
35 self.results == other
36 }
37}
38
39impl PartialEq<Vec<Vec<DataType>>> for Results {
40 fn eq(&self, other: &Vec<Vec<DataType>>) -> bool {
41 &self.results == other
42 }
43}
44
45impl PartialEq<&'_ Vec<Vec<DataType>>> for Results {
46 fn eq(&self, other: &&Vec<Vec<DataType>>) -> bool {
47 &self.results == *other
48 }
49}
50
51#[derive(PartialEq, Eq)]
56pub struct ResultRow<'a> {
57 result: &'a Vec<DataType>,
58 columns: &'a [String],
59}
60
61impl<'a> ResultRow<'a> {
62 fn new(row: &'a Vec<DataType>, columns: &'a [String]) -> Self {
63 Self {
64 result: row,
65 columns,
66 }
67 }
68}
69
70impl std::ops::Index<usize> for ResultRow<'_> {
71 type Output = DataType;
72 fn index(&self, index: usize) -> &Self::Output {
73 &self.result[index]
74 }
75}
76
77impl std::ops::Index<&'_ str> for ResultRow<'_> {
78 type Output = DataType;
79 fn index(&self, index: &'_ str) -> &Self::Output {
80 let index = self.columns.iter().position(|col| col == index).unwrap();
81 &self.result[index]
82 }
83}
84
85impl<'a> ResultRow<'a> {
86 pub fn get<T>(&self, field: &str) -> Option<T>
92 where
93 &'a DataType: Into<T>,
94 {
95 let index = self.columns.iter().position(|col| col == field)?;
96 Some((&self.result[index]).into())
97 }
98}
99
100impl PartialEq<[DataType]> for ResultRow<'_> {
101 fn eq(&self, other: &[DataType]) -> bool {
102 &self.result[..] == other
103 }
104}
105
106impl PartialEq<Vec<DataType>> for ResultRow<'_> {
107 fn eq(&self, other: &Vec<DataType>) -> bool {
108 self.result == other
109 }
110}
111
112impl PartialEq<&'_ Vec<DataType>> for ResultRow<'_> {
113 fn eq(&self, other: &&Vec<DataType>) -> bool {
114 &self.result == other
115 }
116}
117
118impl fmt::Debug for ResultRow<'_> {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
120 f.debug_map()
121 .entries(self.columns.iter().zip(self.result.iter()))
122 .finish()
123 }
124}
125
126impl fmt::Debug for Results {
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
128 f.debug_list()
129 .entries(self.results.iter().map(|r| ResultRow {
130 result: r,
131 columns: &self.columns,
132 }))
133 .finish()
134 }
135}
136
137impl Deref for Results {
138 type Target = [Vec<DataType>];
139 fn deref(&self) -> &Self::Target {
140 &self.results
141 }
142}
143
144impl AsRef<[Vec<DataType>]> for Results {
145 fn as_ref(&self) -> &[Vec<DataType>] {
146 &self.results
147 }
148}
149
150pub struct ResultIter<'a> {
151 results: std::slice::Iter<'a, Vec<DataType>>,
152 columns: &'a [String],
153}
154
155impl<'a> IntoIterator for &'a Results {
156 type Item = ResultRow<'a>;
157 type IntoIter = ResultIter<'a>;
158 fn into_iter(self) -> Self::IntoIter {
159 ResultIter {
160 results: self.results.iter(),
161 columns: &self.columns,
162 }
163 }
164}
165
166impl<'a> Iterator for ResultIter<'a> {
167 type Item = ResultRow<'a>;
168 fn next(&mut self) -> Option<Self::Item> {
169 Some(ResultRow::new(self.results.next()?, &self.columns))
170 }
171
172 fn size_hint(&self) -> (usize, Option<usize>) {
173 self.results.size_hint()
174 }
175}
176
177impl ExactSizeIterator for ResultIter<'_> {}
178impl DoubleEndedIterator for ResultIter<'_> {
179 fn next_back(&mut self) -> Option<Self::Item> {
180 Some(ResultRow::new(self.results.next_back()?, &self.columns))
181 }
182
183 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
184 Some(ResultRow::new(self.results.nth_back(n)?, &self.columns))
185 }
186}
187
188pub struct ResultIntoIter {
189 results: std::vec::IntoIter<Vec<DataType>>,
190 columns: Arc<[String]>,
191}
192
193impl IntoIterator for Results {
194 type Item = Row;
195 type IntoIter = ResultIntoIter;
196 fn into_iter(self) -> Self::IntoIter {
197 ResultIntoIter {
198 results: self.results.into_iter(),
199 columns: self.columns,
200 }
201 }
202}
203
204impl Iterator for ResultIntoIter {
205 type Item = Row;
206 fn next(&mut self) -> Option<Self::Item> {
207 Some(Row::new(self.results.next()?, &self.columns))
208 }
209
210 fn size_hint(&self) -> (usize, Option<usize>) {
211 self.results.size_hint()
212 }
213}
214
215impl ExactSizeIterator for ResultIntoIter {}
216impl DoubleEndedIterator for ResultIntoIter {
217 fn next_back(&mut self) -> Option<Self::Item> {
218 Some(Row::new(self.results.next_back()?, &self.columns))
219 }
220
221 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
222 Some(Row::new(self.results.nth_back(n)?, &self.columns))
223 }
224}
225
226#[derive(PartialEq, Eq)]
231pub struct Row {
232 row: Vec<DataType>,
233 columns: Arc<[String]>,
234}
235
236impl Row {
237 fn new(row: Vec<DataType>, columns: &Arc<[String]>) -> Self {
238 Self {
239 row,
240 columns: Arc::clone(columns),
241 }
242 }
243}
244
245impl Into<Vec<DataType>> for Row {
246 fn into(self) -> Vec<DataType> {
247 self.row
248 }
249}
250
251impl PartialEq<[DataType]> for Row {
252 fn eq(&self, other: &[DataType]) -> bool {
253 self.row == other
254 }
255}
256
257impl PartialEq<Vec<DataType>> for Row {
258 fn eq(&self, other: &Vec<DataType>) -> bool {
259 &self.row == other
260 }
261}
262
263impl PartialEq<&'_ Vec<DataType>> for Row {
264 fn eq(&self, other: &&Vec<DataType>) -> bool {
265 &self.row == *other
266 }
267}
268
269impl fmt::Debug for Row {
270 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
271 f.debug_map()
272 .entries(self.columns.iter().zip(self.row.iter()))
273 .finish()
274 }
275}
276
277impl IntoIterator for Row {
278 type Item = DataType;
279 type IntoIter = std::vec::IntoIter<DataType>;
280 fn into_iter(self) -> Self::IntoIter {
281 self.row.into_iter()
282 }
283}
284
285impl AsRef<[DataType]> for Row {
286 fn as_ref(&self) -> &[DataType] {
287 &self.row[..]
288 }
289}
290
291impl Deref for Row {
292 type Target = [DataType];
293 fn deref(&self) -> &Self::Target {
294 &self.row[..]
295 }
296}
297
298impl std::ops::Index<usize> for Row {
299 type Output = DataType;
300 fn index(&self, index: usize) -> &Self::Output {
301 &self.row[index]
302 }
303}
304
305impl std::ops::Index<&'_ str> for Row {
306 type Output = DataType;
307 fn index(&self, index: &'_ str) -> &Self::Output {
308 let index = self.columns.iter().position(|col| col == index).unwrap();
309 &self.row[index]
310 }
311}
312
313impl Row {
314 pub fn get<T>(&self, field: &str) -> Option<T>
320 where
321 for<'a> &'a DataType: Into<T>,
322 {
323 let index = self.columns.iter().position(|col| col == field)?;
324 Some((&self.row[index]).into())
325 }
326
327 pub fn take(&mut self, field: &str) -> Option<DataType> {
331 let index = self.columns.iter().position(|col| col == field)?;
332 Some(std::mem::replace(&mut self.row[index], DataType::None))
333 }
334}