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>
101 = AggregateMeta<'a>
102 where
103 Self: 'a;
104 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
105 unsafe {
106 match cass_iterator_next(self.0) {
107 cass_false => None,
108 cass_true => {
109 let field_value = cass_iterator_get_aggregate_meta(self.0);
110 Some(AggregateMeta::build(field_value))
111 }
112 }
113 }
114 }
115}
116
117#[derive(Debug)]
124pub struct UserTypeIterator<'a>(*mut _CassIterator, PhantomData<&'a _CassValue>);
125
126unsafe impl Send for UserTypeIterator<'_> {}
129unsafe impl Sync for UserTypeIterator<'_> {}
130
131impl Drop for UserTypeIterator<'_> {
132 fn drop(&mut self) {
133 unsafe { cass_iterator_free(self.0) }
134 }
135}
136
137impl LendingIterator for UserTypeIterator<'_> {
138 type Item<'a>
139 = (String, Value<'a>)
140 where
141 Self: 'a;
142 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
143 unsafe {
144 match cass_iterator_next(self.0) {
145 cass_false => None,
146 cass_true => Some((self.get_field_name(), self.get_field_value())),
147 }
148 }
149 }
150}
151
152impl UserTypeIterator<'_> {
153 fn get_field_name(&self) -> String {
154 unsafe {
155 let mut name = std::ptr::null();
156 let mut name_length = 0;
157 cass_iterator_get_user_type_field_name(self.0, &mut name, &mut name_length)
158 .to_result(())
159 .and_then(|_| {
160 let slice = slice::from_raw_parts(name as *const u8, name_length);
161 let name = str::from_utf8(slice)?.to_owned();
162 Ok(name)
163 })
164 .expect("Cassandra error during iteration")
165 }
166 }
167
168 fn get_field_value(&self) -> Value<'_> {
169 unsafe { Value::build(cass_iterator_get_user_type_field_value(self.0)) }
170 }
171}
172
173#[derive(Debug)]
180pub struct FunctionIterator<'a>(*mut _CassIterator, PhantomData<&'a CassKeyspaceMeta>);
181
182unsafe impl Send for FunctionIterator<'_> {}
185unsafe impl Sync for FunctionIterator<'_> {}
186
187impl LendingIterator for FunctionIterator<'_> {
188 type Item<'a>
189 = FunctionMeta<'a>
190 where
191 Self: 'a;
192 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
193 unsafe {
194 match cass_iterator_next(self.0) {
195 cass_false => None,
196 cass_true => Some(FunctionMeta::build(cass_iterator_get_function_meta(self.0))),
197 }
198 }
199 }
200}
201
202#[derive(Debug)]
209pub struct TableIterator<'a>(*mut _CassIterator, PhantomData<&'a CassKeyspaceMeta>);
210
211unsafe impl Send for TableIterator<'_> {}
214unsafe impl Sync for TableIterator<'_> {}
215
216impl LendingIterator for TableIterator<'_> {
217 type Item<'a>
218 = TableMeta<'a>
219 where
220 Self: 'a;
221 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
222 unsafe {
223 match cass_iterator_next(self.0) {
224 cass_false => None,
225 cass_true => Some(TableMeta::build(cass_iterator_get_table_meta(self.0))),
226 }
227 }
228 }
229}
230
231#[derive(Debug)]
238pub struct KeyspaceIterator<'a>(*mut _CassIterator, PhantomData<&'a CassSchemaMeta>);
239
240unsafe impl Send for KeyspaceIterator<'_> {}
243unsafe impl Sync for KeyspaceIterator<'_> {}
244
245impl LendingIterator for KeyspaceIterator<'_> {
246 type Item<'a>
247 = KeyspaceMeta<'a>
248 where
249 Self: 'a;
250 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
251 unsafe {
252 match cass_iterator_next(self.0) {
253 cass_false => None,
254 cass_true => Some(KeyspaceMeta::build(cass_iterator_get_keyspace_meta(self.0))),
255 }
256 }
257 }
258}
259
260#[derive(Debug)]
267pub struct ColumnIterator<'a>(*mut _CassIterator, PhantomData<&'a CassTableMeta>);
268
269unsafe impl Send for ColumnIterator<'_> {}
272unsafe impl Sync for ColumnIterator<'_> {}
273
274impl LendingIterator for ColumnIterator<'_> {
275 type Item<'a>
276 = ColumnMeta<'a>
277 where
278 Self: 'a;
279 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
280 unsafe {
281 match cass_iterator_next(self.0) {
282 cass_false => None,
283 cass_true => Some(ColumnMeta::build(cass_iterator_get_column_meta(self.0))),
284 }
285 }
286 }
287}
288
289#[derive(Debug)]
299pub struct FieldIterator<'a>(*mut _CassIterator, PhantomData<&'a CassTableMeta>);
300
301unsafe impl Send for FieldIterator<'_> {}
304unsafe impl Sync for FieldIterator<'_> {}
305
306impl LendingIterator for FieldIterator<'_> {
307 type Item<'a>
308 = Field<'a>
309 where
310 Self: 'a;
311
312 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
313 unsafe {
314 match cass_iterator_next(self.0) {
315 cass_false => None,
316 cass_true => {
317 let mut name = std::ptr::null();
318 let mut name_length = 0;
319 cass_iterator_get_meta_field_name(self.0, &mut name, &mut name_length)
320 .to_result(())
321 .and_then(|_| {
322 let slice = slice::from_raw_parts(name as *const u8, name_length);
323 let name = str::from_utf8(slice)?.to_owned();
324 let value = Value::build(cass_iterator_get_meta_field_value(self.0));
325 Ok(Some(Field { name, value }))
326 })
327 }
328 .expect("Cassandra error during iteration"),
329 }
330 }
331 }
332}
333
334impl ProtectedInner<*mut _CassIterator> for UserTypeIterator<'_> {
335 fn inner(&self) -> *mut _CassIterator {
336 self.0
337 }
338}
339
340impl Protected<*mut _CassIterator> for UserTypeIterator<'_> {
341 fn build(inner: *mut _CassIterator) -> Self {
342 if inner.is_null() {
343 panic!("Unexpected null pointer")
344 };
345 UserTypeIterator(inner, PhantomData)
346 }
347}
348
349impl ProtectedInner<*mut _CassIterator> for AggregateIterator<'_> {
350 fn inner(&self) -> *mut _CassIterator {
351 self.0
352 }
353}
354
355impl Protected<*mut _CassIterator> for AggregateIterator<'_> {
356 fn build(inner: *mut _CassIterator) -> Self {
357 if inner.is_null() {
358 panic!("Unexpected null pointer")
359 };
360 AggregateIterator(inner, PhantomData)
361 }
362}
363
364impl ProtectedInner<*mut _CassIterator> for FunctionIterator<'_> {
365 fn inner(&self) -> *mut _CassIterator {
366 self.0
367 }
368}
369
370impl Protected<*mut _CassIterator> for FunctionIterator<'_> {
371 fn build(inner: *mut _CassIterator) -> Self {
372 if inner.is_null() {
373 panic!("Unexpected null pointer")
374 };
375 FunctionIterator(inner, PhantomData)
376 }
377}
378
379impl ProtectedInner<*mut _CassIterator> for KeyspaceIterator<'_> {
380 fn inner(&self) -> *mut _CassIterator {
381 self.0
382 }
383}
384
385impl Protected<*mut _CassIterator> for KeyspaceIterator<'_> {
386 fn build(inner: *mut _CassIterator) -> Self {
387 if inner.is_null() {
388 panic!("Unexpected null pointer")
389 };
390 KeyspaceIterator(inner, PhantomData)
391 }
392}
393
394impl ProtectedInner<*mut _CassIterator> for FieldIterator<'_> {
395 fn inner(&self) -> *mut _CassIterator {
396 self.0
397 }
398}
399impl Protected<*mut _CassIterator> for FieldIterator<'_> {
400 fn build(inner: *mut _CassIterator) -> Self {
401 if inner.is_null() {
402 panic!("Unexpected null pointer")
403 };
404 FieldIterator(inner, PhantomData)
405 }
406}
407
408impl ProtectedInner<*mut _CassIterator> for ColumnIterator<'_> {
409 fn inner(&self) -> *mut _CassIterator {
410 self.0
411 }
412}
413
414impl Protected<*mut _CassIterator> for ColumnIterator<'_> {
415 fn build(inner: *mut _CassIterator) -> Self {
416 if inner.is_null() {
417 panic!("Unexpected null pointer")
418 };
419 ColumnIterator(inner, PhantomData)
420 }
421}
422
423impl ProtectedInner<*mut _CassIterator> for TableIterator<'_> {
424 fn inner(&self) -> *mut _CassIterator {
425 self.0
426 }
427}
428
429impl Protected<*mut _CassIterator> for TableIterator<'_> {
430 fn build(inner: *mut _CassIterator) -> Self {
431 if inner.is_null() {
432 panic!("Unexpected null pointer")
433 };
434 TableIterator(inner, PhantomData)
435 }
436}
437
438impl ProtectedInner<*mut _CassIterator> for MapIterator<'_> {
439 fn inner(&self) -> *mut _CassIterator {
440 self.0
441 }
442}
443
444impl Protected<*mut _CassIterator> for MapIterator<'_> {
445 fn build(inner: *mut _CassIterator) -> Self {
446 if inner.is_null() {
447 panic!("Unexpected null pointer")
448 };
449 MapIterator(inner, PhantomData)
450 }
451}
452
453impl ProtectedInner<*mut _CassIterator> for SetIterator<'_> {
454 fn inner(&self) -> *mut _CassIterator {
455 self.0
456 }
457}
458
459impl Protected<*mut _CassIterator> for SetIterator<'_> {
460 fn build(inner: *mut _CassIterator) -> Self {
461 if inner.is_null() {
462 panic!("Unexpected null pointer")
463 };
464 SetIterator(inner, PhantomData)
465 }
466}
467
468#[derive(Debug)]
475pub struct SetIterator<'a>(*mut _CassIterator, PhantomData<&'a _CassValue>);
476
477unsafe impl Send for SetIterator<'_> {}
480unsafe impl Sync for SetIterator<'_> {}
481
482impl Drop for SetIterator<'_> {
483 fn drop(&mut self) {
484 unsafe { cass_iterator_free(self.0) }
485 }
486}
487
488impl LendingIterator for SetIterator<'_> {
489 type Item<'a>
490 = Value<'a>
491 where
492 Self: 'a;
493
494 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
495 unsafe {
496 match cass_iterator_next(self.0) {
497 cass_false => None,
498 cass_true => Some(self.get_value()),
499 }
500 }
501 }
502}
503
504impl SetIterator<'_> {
505 fn get_value(&self) -> Value<'_> {
506 unsafe { Value::build(cass_iterator_get_value(self.0)) }
507 }
508}
509
510#[derive(Debug)]
512pub struct MapIterator<'a>(*mut _CassIterator, PhantomData<&'a _CassValue>);
518
519unsafe impl Send for MapIterator<'_> {}
522unsafe impl Sync for MapIterator<'_> {}
523
524impl MapIterator<'_> {
525 fn get_key(&self) -> Value<'_> {
526 unsafe { Value::build(cass_iterator_get_map_key(self.0)) }
527 }
528 fn get_value(&self) -> Value<'_> {
529 unsafe { Value::build(cass_iterator_get_map_value(self.0)) }
530 }
531
532 pub fn get_pair(&self) -> (Value<'_>, Value<'_>) {
534 (self.get_key(), self.get_value())
535 }
536}
537
538impl Drop for MapIterator<'_> {
539 fn drop(&mut self) {
540 unsafe { cass_iterator_free(self.0) }
541 }
542}
543
544impl LendingIterator for MapIterator<'_> {
545 type Item<'a>
546 = (Value<'a>, Value<'a>)
547 where
548 Self: 'a;
549 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
550 unsafe {
551 match cass_iterator_next(self.0) {
552 cass_false => None,
553 cass_true => Some(self.get_pair()),
554 }
555 }
556 }
557}