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