discord_cassandra_cpp/cassandra/
row.rs1use crate::cassandra::error::*;
2
3use crate::cassandra::inet::Inet;
4use crate::cassandra::iterator::{MapIterator, SetIterator, UserTypeIterator};
5use crate::cassandra::result::CassResult;
6use crate::cassandra::util::{Protected, ProtectedInner};
7use crate::cassandra::uuid::Uuid;
8use crate::cassandra::value::Value;
9use crate::cassandra_sys::cass_false;
10use crate::cassandra_sys::cass_iterator_free;
11use crate::cassandra_sys::cass_iterator_from_row;
12use crate::cassandra_sys::cass_iterator_get_column;
13use crate::cassandra_sys::cass_iterator_next;
14use crate::cassandra_sys::cass_row_get_column;
15use crate::cassandra_sys::cass_row_get_column_by_name_n;
16use crate::cassandra_sys::cass_true;
17use crate::cassandra_sys::CassIterator as _CassIterator;
18use crate::cassandra_sys::CassRow as _Row;
19use std::fmt;
20use std::fmt::Debug;
21use std::fmt::Display;
22use std::fmt::Formatter;
23use std::iter;
24use std::iter::IntoIterator;
25use std::marker::PhantomData;
26use std::os::raw::c_char;
27
28pub struct Row<'a>(*const _Row, PhantomData<&'a CassResult>);
30
31unsafe impl<'a> Sync for Row<'a> {}
32unsafe impl<'a> Send for Row<'a> {}
33
34impl<'a> ProtectedInner<*const _Row> for Row<'a> {
35 fn inner(&self) -> *const _Row {
36 self.0
37 }
38}
39
40impl<'a> Protected<*const _Row> for Row<'a> {
41 fn build(inner: *const _Row) -> Self {
42 if inner.is_null() {
43 panic!("Unexpected null pointer")
44 };
45 Row(inner, PhantomData)
46 }
47}
48
49impl<'a> Debug for Row<'a> {
50 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
51 for column in self {
52 write!(f, "{:?}\t", Value::build(column.inner()))?;
53 }
54 Ok(())
55 }
56}
57
58impl<'a> Display for Row<'a> {
59 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
60 for column in self {
61 write!(f, "{}\t", Value::build(column.inner()))?;
62 }
63 Ok(())
64 }
65}
66
67pub trait AsRustType<T> {
69 fn get(&self, index: usize) -> Result<T>;
71
72 fn get_by_name<S>(&self, name: S) -> Result<T>
74 where
75 S: Into<String>;
76}
77
78impl AsRustType<bool> for Row<'_> {
79 fn get(&self, index: usize) -> Result<bool> {
80 let col = self.get_column(index)?;
81 col.get_bool()
82 }
83
84 fn get_by_name<S>(&self, name: S) -> Result<bool>
85 where
86 S: Into<String>,
87 {
88 self.get_column_by_name(name)?.get_bool()
89 }
90}
91
92impl AsRustType<String> for Row<'_> {
93 fn get(&self, index: usize) -> Result<String> {
94 let col = self.get_column(index)?;
95 col.get_string()
96 }
97
98 fn get_by_name<S>(&self, name: S) -> Result<String>
99 where
100 S: Into<String>,
101 {
102 let col = self.get_column_by_name(name)?;
103 col.get_string()
104 }
105}
106
107impl AsRustType<f64> for Row<'_> {
108 fn get(&self, index: usize) -> Result<f64> {
109 let col = self.get_column(index)?;
110 col.get_f64()
111 }
112
113 fn get_by_name<S>(&self, name: S) -> Result<f64>
114 where
115 S: Into<String>,
116 {
117 let col = self.get_column_by_name(name)?;
118 col.get_f64()
119 }
120}
121
122impl AsRustType<f32> for Row<'_> {
123 fn get(&self, index: usize) -> Result<f32> {
124 let col = self.get_column(index)?;
125 col.get_f32()
126 }
127
128 fn get_by_name<S>(&self, name: S) -> Result<f32>
129 where
130 S: Into<String>,
131 {
132 let col = self.get_column_by_name(name)?;
133 col.get_f32()
134 }
135}
136
137impl AsRustType<i64> for Row<'_> {
138 fn get(&self, index: usize) -> Result<i64> {
139 let col = self.get_column(index)?;
140 col.get_i64()
141 }
142
143 fn get_by_name<S>(&self, name: S) -> Result<i64>
144 where
145 S: Into<String>,
146 {
147 let col = self.get_column_by_name(name)?;
148 col.get_i64()
149 }
150}
151
152impl AsRustType<i32> for Row<'_> {
153 fn get(&self, index: usize) -> Result<i32> {
154 let col = self.get_column(index)?;
155 col.get_i32()
156 }
157
158 fn get_by_name<S>(&self, name: S) -> Result<i32>
159 where
160 S: Into<String>,
161 {
162 let col = self.get_column_by_name(name)?;
163 col.get_i32()
164 }
165}
166
167impl AsRustType<i16> for Row<'_> {
168 fn get(&self, index: usize) -> Result<i16> {
169 let col = self.get_column(index)?;
170 col.get_i16()
171 }
172
173 fn get_by_name<S>(&self, name: S) -> Result<i16>
174 where
175 S: Into<String>,
176 {
177 let col = self.get_column_by_name(name)?;
178 col.get_i16()
179 }
180}
181
182impl AsRustType<i8> for Row<'_> {
183 fn get(&self, index: usize) -> Result<i8> {
184 let col = self.get_column(index)?;
185 col.get_i8()
186 }
187
188 fn get_by_name<S>(&self, name: S) -> Result<i8>
189 where
190 S: Into<String>,
191 {
192 let col = self.get_column_by_name(name)?;
193 col.get_i8()
194 }
195}
196
197impl AsRustType<u32> for Row<'_> {
198 fn get(&self, index: usize) -> Result<u32> {
199 let col = self.get_column(index)?;
200 col.get_u32()
201 }
202
203 fn get_by_name<S>(&self, name: S) -> Result<u32>
204 where
205 S: Into<String>,
206 {
207 let col = self.get_column_by_name(name)?;
208 col.get_u32()
209 }
210}
211
212impl AsRustType<Inet> for Row<'_> {
213 fn get(&self, index: usize) -> Result<Inet> {
214 let col = self.get_column(index)?;
215 col.get_inet()
216 }
217
218 fn get_by_name<S>(&self, name: S) -> Result<Inet>
219 where
220 S: Into<String>,
221 {
222 let col = self.get_column_by_name(name)?;
223 col.get_inet()
224 }
225}
226
227impl AsRustType<SetIterator> for Row<'_> {
228 fn get(&self, index: usize) -> Result<SetIterator> {
229 let col = self.get_column(index)?;
230 col.get_set()
231 }
232
233 fn get_by_name<S>(&self, name: S) -> Result<SetIterator>
234 where
235 S: Into<String>,
236 {
237 let col = self.get_column_by_name(name)?;
238 col.get_set()
239 }
240}
241
242impl AsRustType<MapIterator> for Row<'_> {
243 fn get(&self, index: usize) -> Result<MapIterator> {
244 let col = self.get_column(index)?;
245 col.get_map()
246 }
247
248 fn get_by_name<S>(&self, name: S) -> Result<MapIterator>
249 where
250 S: Into<String>,
251 {
252 let col = self.get_column_by_name(name)?;
253 col.get_map()
254 }
255}
256
257impl AsRustType<UserTypeIterator> for Row<'_> {
258 fn get(&self, index: usize) -> Result<UserTypeIterator> {
259 let col = self.get_column(index)?;
260 col.get_user_type()
261 }
262
263 fn get_by_name<S>(&self, name: S) -> Result<UserTypeIterator>
264 where
265 S: Into<String>,
266 {
267 let col = self.get_column_by_name(name)?;
268 col.get_user_type()
269 }
270}
271
272impl AsRustType<Uuid> for Row<'_> {
273 fn get(&self, index: usize) -> Result<Uuid> {
274 let col = self.get_column(index)?;
275 col.get_uuid()
276 }
277
278 fn get_by_name<S>(&self, name: S) -> Result<Uuid>
279 where
280 S: Into<String>,
281 {
282 let col = self.get_column_by_name(name)?;
283 col.get_uuid()
284 }
285}
286
287impl AsRustType<uuid::Uuid> for Row<'_> {
288 fn get(&self, index: usize) -> Result<uuid::Uuid> {
289 let col = self.get_column(index)?;
290 col.get_uuid().map(|x| x.into())
291 }
292
293 fn get_by_name<S>(&self, name: S) -> Result<uuid::Uuid>
294 where
295 S: Into<String>,
296 {
297 let col = self.get_column_by_name(name)?;
298 col.get_uuid().map(|x| x.into())
299 }
300}
301
302impl AsRustType<Vec<u8>> for Row<'_> {
303 fn get(&self, index: usize) -> Result<Vec<u8>> {
304 let col = self.get_column(index)?;
305 col.get_bytes().map(|b| b.to_vec())
306 }
307
308 fn get_by_name<S>(&self, name: S) -> Result<Vec<u8>>
309 where
310 S: Into<String>,
311 {
312 let col = self.get_column_by_name(name)?;
313 col.get_bytes().map(|b| b.to_vec())
314 }
315}
316
317impl<'a> Row<'a> {
318 pub fn get_column(&self, index: usize) -> Result<Value> {
320 unsafe {
321 let col = cass_row_get_column(self.0, index);
322 if col.is_null() {
323 Err(CassErrorCode::LIB_INDEX_OUT_OF_BOUNDS.to_error())
324 } else {
325 Ok(Value::build(col))
326 }
327 }
328 }
329
330 pub fn get_column_by_name<S>(&self, name: S) -> Result<Value>
332 where
333 S: Into<String>,
334 {
335 unsafe {
336 let name_str = name.into();
337 let name_ptr = name_str.as_ptr() as *const c_char;
338 let col = cass_row_get_column_by_name_n(self.0, name_ptr, name_str.len());
339 if col.is_null() {
340 Err(CassErrorCode::LIB_INDEX_OUT_OF_BOUNDS.to_error())
341 } else {
342 Ok(Value::build(col))
343 }
344 }
345 }
346}
347
348#[derive(Debug)]
350pub struct RowIterator(pub *mut _CassIterator);
351
352unsafe impl Send for RowIterator {}
355
356impl Drop for RowIterator {
357 fn drop(&mut self) {
358 unsafe { cass_iterator_free(self.0) }
359 }
360}
361
362impl iter::Iterator for RowIterator {
363 type Item = Value;
364
365 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
366 unsafe {
367 match cass_iterator_next(self.0) {
368 cass_false => None,
369 cass_true => Some(Value::build(cass_iterator_get_column(self.0))),
370 }
371 }
372 }
373}
374
375impl<'a> Iterator for &'a RowIterator {
376 type Item = Value;
377
378 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
379 unsafe {
380 match cass_iterator_next(self.0) {
381 cass_false => None,
382 cass_true => Some(Value::build(cass_iterator_get_column(self.0))),
383 }
384 }
385 }
386}
387
388impl Display for RowIterator {
389 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
390 for item in self {
391 write!(f, "{}\t", Value::build(item.inner()))?;
392 }
393 Ok(())
394 }
395}
396
397impl IntoIterator for Row<'_> {
398 type Item = Value;
399 type IntoIter = RowIterator;
400
401 fn into_iter(self) -> Self::IntoIter {
404 unsafe { RowIterator(cass_iterator_from_row(self.0)) }
405 }
406}
407
408impl<'a> IntoIterator for &'a Row<'_> {
409 type Item = Value;
410 type IntoIter = RowIterator;
411 fn into_iter(self) -> Self::IntoIter {
412 unsafe { RowIterator(cass_iterator_from_row(self.0)) }
413 }
414}