cassandra_cpp/cassandra/
iterator.rs1use crate::cassandra::error::*;
2use crate::cassandra::field::Field;
3use crate::cassandra::schema::aggregate_meta::AggregateMeta;
4use crate::cassandra::schema::column_meta::ColumnMeta;
5use crate::cassandra::schema::function_meta::FunctionMeta;
6use crate::cassandra::schema::keyspace_meta::KeyspaceMeta;
7use crate::cassandra::schema::table_meta::TableMeta;
8use crate::cassandra::util::{Protected, ProtectedInner};
9use crate::cassandra::value::Value;
10
11use crate::cassandra_sys::cass_false;
13use crate::cassandra_sys::CassIterator as _CassIterator;
14use crate::cassandra_sys::cass_iterator_free;
16use crate::cassandra_sys::cass_iterator_get_aggregate_meta;
17use crate::cassandra_sys::cass_iterator_get_column_meta;
18use crate::cassandra_sys::cass_iterator_get_function_meta;
19use crate::cassandra_sys::cass_iterator_get_keyspace_meta;
20use crate::cassandra_sys::cass_iterator_get_map_key;
21use crate::cassandra_sys::cass_iterator_get_map_value;
22use crate::cassandra_sys::cass_iterator_get_meta_field_name;
23use crate::cassandra_sys::cass_iterator_get_meta_field_value;
24use crate::cassandra_sys::cass_iterator_get_table_meta;
25use crate::cassandra_sys::cass_iterator_get_user_type_field_name;
26use crate::cassandra_sys::cass_iterator_get_user_type_field_value;
27use crate::cassandra_sys::cass_iterator_get_value;
28use crate::cassandra_sys::cass_iterator_next;
29use crate::cassandra_sys::cass_true;
30use crate::cassandra_sys::CassKeyspaceMeta;
31use crate::cassandra_sys::CassSchemaMeta;
32use crate::cassandra_sys::CassTableMeta;
33use crate::cassandra_sys::CassValue as _CassValue;
34
35use std::marker::PhantomData;
36use std::{slice, str};
37
38pub trait LendingIterator {
63 type Item<'a>
65 where
66 Self: 'a;
67
68 fn next(&mut self) -> Option<Self::Item<'_>>;
71
72 fn size_hint(&self) -> (usize, Option<usize>) {
75 (0, None)
76 }
77}
78
79#[derive(Debug)]
86pub struct AggregateIterator<'a>(*mut _CassIterator, PhantomData<&'a CassKeyspaceMeta>);
87
88unsafe impl Send for AggregateIterator<'_> {}
91unsafe impl Sync for AggregateIterator<'_> {}
92
93impl Drop for AggregateIterator<'_> {
94 fn drop(&mut self) {
95 unsafe { cass_iterator_free(self.0) }
96 }
97}
98
99impl LendingIterator for AggregateIterator<'_> {
100 type Item<'a> = AggregateMeta<'a> where Self: 'a;
101 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
102 unsafe {
103 match cass_iterator_next(self.0) {
104 cass_false => None,
105 cass_true => {
106 let field_value = cass_iterator_get_aggregate_meta(self.0);
107 Some(AggregateMeta::build(field_value))
108 }
109 }
110 }
111 }
112}
113
114#[derive(Debug)]
121pub struct UserTypeIterator<'a>(*mut _CassIterator, PhantomData<&'a _CassValue>);
122
123unsafe impl Send for UserTypeIterator<'_> {}
126unsafe impl Sync for UserTypeIterator<'_> {}
127
128impl Drop for UserTypeIterator<'_> {
129 fn drop(&mut self) {
130 unsafe { cass_iterator_free(self.0) }
131 }
132}
133
134impl LendingIterator for UserTypeIterator<'_> {
135 type Item<'a> = (String, Value<'a>) where Self: 'a;
136 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
137 unsafe {
138 match cass_iterator_next(self.0) {
139 cass_false => None,
140 cass_true => Some((self.get_field_name(), self.get_field_value())),
141 }
142 }
143 }
144}
145
146impl UserTypeIterator<'_> {
147 fn get_field_name(&self) -> String {
148 unsafe {
149 let mut name = std::ptr::null();
150 let mut name_length = 0;
151 cass_iterator_get_user_type_field_name(self.0, &mut name, &mut name_length)
152 .to_result(())
153 .and_then(|_| {
154 let slice = slice::from_raw_parts(name as *const u8, name_length);
155 let name = str::from_utf8(slice)?.to_owned();
156 Ok(name)
157 })
158 .expect("Cassandra error during iteration")
159 }
160 }
161
162 fn get_field_value(&self) -> Value {
163 unsafe { Value::build(cass_iterator_get_user_type_field_value(self.0)) }
164 }
165}
166
167#[derive(Debug)]
174pub struct FunctionIterator<'a>(*mut _CassIterator, PhantomData<&'a CassKeyspaceMeta>);
175
176unsafe impl Send for FunctionIterator<'_> {}
179unsafe impl Sync for FunctionIterator<'_> {}
180
181impl LendingIterator for FunctionIterator<'_> {
182 type Item<'a> = FunctionMeta<'a> where Self: 'a;
183 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
184 unsafe {
185 match cass_iterator_next(self.0) {
186 cass_false => None,
187 cass_true => Some(FunctionMeta::build(cass_iterator_get_function_meta(self.0))),
188 }
189 }
190 }
191}
192
193#[derive(Debug)]
200pub struct TableIterator<'a>(*mut _CassIterator, PhantomData<&'a CassKeyspaceMeta>);
201
202unsafe impl Send for TableIterator<'_> {}
205unsafe impl Sync for TableIterator<'_> {}
206
207impl LendingIterator for TableIterator<'_> {
208 type Item<'a> = TableMeta<'a> where Self: 'a;
209 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
210 unsafe {
211 match cass_iterator_next(self.0) {
212 cass_false => None,
213 cass_true => Some(TableMeta::build(cass_iterator_get_table_meta(self.0))),
214 }
215 }
216 }
217}
218
219#[derive(Debug)]
226pub struct KeyspaceIterator<'a>(*mut _CassIterator, PhantomData<&'a CassSchemaMeta>);
227
228unsafe impl Send for KeyspaceIterator<'_> {}
231unsafe impl Sync for KeyspaceIterator<'_> {}
232
233impl LendingIterator for KeyspaceIterator<'_> {
234 type Item<'a> = KeyspaceMeta<'a> where Self: 'a;
235 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
236 unsafe {
237 match cass_iterator_next(self.0) {
238 cass_false => None,
239 cass_true => Some(KeyspaceMeta::build(cass_iterator_get_keyspace_meta(self.0))),
240 }
241 }
242 }
243}
244
245#[derive(Debug)]
252pub struct ColumnIterator<'a>(*mut _CassIterator, PhantomData<&'a CassTableMeta>);
253
254unsafe impl Send for ColumnIterator<'_> {}
257unsafe impl Sync for ColumnIterator<'_> {}
258
259impl LendingIterator for ColumnIterator<'_> {
260 type Item<'a> = ColumnMeta<'a> where Self: 'a;
261 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
262 unsafe {
263 match cass_iterator_next(self.0) {
264 cass_false => None,
265 cass_true => Some(ColumnMeta::build(cass_iterator_get_column_meta(self.0))),
266 }
267 }
268 }
269}
270
271#[derive(Debug)]
281pub struct FieldIterator<'a>(*mut _CassIterator, PhantomData<&'a CassTableMeta>);
282
283unsafe impl Send for FieldIterator<'_> {}
286unsafe impl Sync for FieldIterator<'_> {}
287
288impl LendingIterator for FieldIterator<'_> {
289 type Item<'a> = Field<'a> where Self: 'a;
290
291 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
292 unsafe {
293 match cass_iterator_next(self.0) {
294 cass_false => None,
295 cass_true => {
296 let mut name = std::ptr::null();
297 let mut name_length = 0;
298 cass_iterator_get_meta_field_name(self.0, &mut name, &mut name_length)
299 .to_result(())
300 .and_then(|_| {
301 let slice = slice::from_raw_parts(name as *const u8, name_length);
302 let name = str::from_utf8(slice)?.to_owned();
303 let value = Value::build(cass_iterator_get_meta_field_value(self.0));
304 Ok(Some(Field { name, value }))
305 })
306 }
307 .expect("Cassandra error during iteration"),
308 }
309 }
310 }
311}
312
313impl ProtectedInner<*mut _CassIterator> for UserTypeIterator<'_> {
314 fn inner(&self) -> *mut _CassIterator {
315 self.0
316 }
317}
318
319impl Protected<*mut _CassIterator> for UserTypeIterator<'_> {
320 fn build(inner: *mut _CassIterator) -> Self {
321 if inner.is_null() {
322 panic!("Unexpected null pointer")
323 };
324 UserTypeIterator(inner, PhantomData)
325 }
326}
327
328impl ProtectedInner<*mut _CassIterator> for AggregateIterator<'_> {
329 fn inner(&self) -> *mut _CassIterator {
330 self.0
331 }
332}
333
334impl Protected<*mut _CassIterator> for AggregateIterator<'_> {
335 fn build(inner: *mut _CassIterator) -> Self {
336 if inner.is_null() {
337 panic!("Unexpected null pointer")
338 };
339 AggregateIterator(inner, PhantomData)
340 }
341}
342
343impl ProtectedInner<*mut _CassIterator> for FunctionIterator<'_> {
344 fn inner(&self) -> *mut _CassIterator {
345 self.0
346 }
347}
348
349impl Protected<*mut _CassIterator> for FunctionIterator<'_> {
350 fn build(inner: *mut _CassIterator) -> Self {
351 if inner.is_null() {
352 panic!("Unexpected null pointer")
353 };
354 FunctionIterator(inner, PhantomData)
355 }
356}
357
358impl ProtectedInner<*mut _CassIterator> for KeyspaceIterator<'_> {
359 fn inner(&self) -> *mut _CassIterator {
360 self.0
361 }
362}
363
364impl Protected<*mut _CassIterator> for KeyspaceIterator<'_> {
365 fn build(inner: *mut _CassIterator) -> Self {
366 if inner.is_null() {
367 panic!("Unexpected null pointer")
368 };
369 KeyspaceIterator(inner, PhantomData)
370 }
371}
372
373impl ProtectedInner<*mut _CassIterator> for FieldIterator<'_> {
374 fn inner(&self) -> *mut _CassIterator {
375 self.0
376 }
377}
378impl Protected<*mut _CassIterator> for FieldIterator<'_> {
379 fn build(inner: *mut _CassIterator) -> Self {
380 if inner.is_null() {
381 panic!("Unexpected null pointer")
382 };
383 FieldIterator(inner, PhantomData)
384 }
385}
386
387impl ProtectedInner<*mut _CassIterator> for ColumnIterator<'_> {
388 fn inner(&self) -> *mut _CassIterator {
389 self.0
390 }
391}
392
393impl Protected<*mut _CassIterator> for ColumnIterator<'_> {
394 fn build(inner: *mut _CassIterator) -> Self {
395 if inner.is_null() {
396 panic!("Unexpected null pointer")
397 };
398 ColumnIterator(inner, PhantomData)
399 }
400}
401
402impl ProtectedInner<*mut _CassIterator> for TableIterator<'_> {
403 fn inner(&self) -> *mut _CassIterator {
404 self.0
405 }
406}
407
408impl Protected<*mut _CassIterator> for TableIterator<'_> {
409 fn build(inner: *mut _CassIterator) -> Self {
410 if inner.is_null() {
411 panic!("Unexpected null pointer")
412 };
413 TableIterator(inner, PhantomData)
414 }
415}
416
417impl ProtectedInner<*mut _CassIterator> for MapIterator<'_> {
418 fn inner(&self) -> *mut _CassIterator {
419 self.0
420 }
421}
422
423impl Protected<*mut _CassIterator> for MapIterator<'_> {
424 fn build(inner: *mut _CassIterator) -> Self {
425 if inner.is_null() {
426 panic!("Unexpected null pointer")
427 };
428 MapIterator(inner, PhantomData)
429 }
430}
431
432impl ProtectedInner<*mut _CassIterator> for SetIterator<'_> {
433 fn inner(&self) -> *mut _CassIterator {
434 self.0
435 }
436}
437
438impl Protected<*mut _CassIterator> for SetIterator<'_> {
439 fn build(inner: *mut _CassIterator) -> Self {
440 if inner.is_null() {
441 panic!("Unexpected null pointer")
442 };
443 SetIterator(inner, PhantomData)
444 }
445}
446
447#[derive(Debug)]
454pub struct SetIterator<'a>(*mut _CassIterator, PhantomData<&'a _CassValue>);
455
456unsafe impl Send for SetIterator<'_> {}
459unsafe impl Sync for SetIterator<'_> {}
460
461impl Drop for SetIterator<'_> {
462 fn drop(&mut self) {
463 unsafe { cass_iterator_free(self.0) }
464 }
465}
466
467impl LendingIterator for SetIterator<'_> {
468 type Item<'a> = Value<'a> where Self: 'a;
469
470 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
471 unsafe {
472 match cass_iterator_next(self.0) {
473 cass_false => None,
474 cass_true => Some(self.get_value()),
475 }
476 }
477 }
478}
479
480impl SetIterator<'_> {
481 fn get_value(&self) -> Value {
482 unsafe { Value::build(cass_iterator_get_value(self.0)) }
483 }
484}
485
486#[derive(Debug)]
488pub struct MapIterator<'a>(*mut _CassIterator, PhantomData<&'a _CassValue>);
494
495unsafe impl Send for MapIterator<'_> {}
498unsafe impl Sync for MapIterator<'_> {}
499
500impl MapIterator<'_> {
501 fn get_key(&self) -> Value {
502 unsafe { Value::build(cass_iterator_get_map_key(self.0)) }
503 }
504 fn get_value(&self) -> Value {
505 unsafe { Value::build(cass_iterator_get_map_value(self.0)) }
506 }
507
508 pub fn get_pair(&self) -> (Value, Value) {
510 (self.get_key(), self.get_value())
511 }
512}
513
514impl Drop for MapIterator<'_> {
515 fn drop(&mut self) {
516 unsafe { cass_iterator_free(self.0) }
517 }
518}
519
520impl LendingIterator for MapIterator<'_> {
521 type Item<'a> = (Value<'a>, Value<'a>) where Self: 'a;
522 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
523 unsafe {
524 match cass_iterator_next(self.0) {
525 cass_false => None,
526 cass_true => Some(self.get_pair()),
527 }
528 }
529 }
530}