discord_cassandra_cpp/cassandra/
iterator.rs

1use cassandra_cpp_sys::cass_iterator_get_materialized_view_meta;
2
3use crate::cassandra::data_type::DataType;
4use crate::cassandra::error::*;
5use crate::cassandra::field::Field;
6use crate::cassandra::schema::aggregate_meta::AggregateMeta;
7use crate::cassandra::schema::column_meta::ColumnMeta;
8use crate::cassandra::schema::function_meta::FunctionMeta;
9use crate::cassandra::schema::keyspace_meta::KeyspaceMeta;
10use crate::cassandra::schema::materialized_view_meta::MaterializedViewMeta;
11use crate::cassandra::schema::table_meta::TableMeta;
12use crate::cassandra::util::{Protected, ProtectedInner};
13use crate::cassandra::value::Value;
14
15// use cassandra_sys::CassIteratorType as _CassIteratorType;
16use crate::cassandra_sys::cass_false;
17use crate::cassandra_sys::CassIterator as _CassIterator;
18// use cassandra_sys::cass_iterator_type;
19use crate::cassandra_sys::cass_iterator_free;
20use crate::cassandra_sys::cass_iterator_get_aggregate_meta;
21use crate::cassandra_sys::cass_iterator_get_column_meta;
22use crate::cassandra_sys::cass_iterator_get_function_meta;
23use crate::cassandra_sys::cass_iterator_get_keyspace_meta;
24use crate::cassandra_sys::cass_iterator_get_map_key;
25use crate::cassandra_sys::cass_iterator_get_map_value;
26use crate::cassandra_sys::cass_iterator_get_meta_field_name;
27use crate::cassandra_sys::cass_iterator_get_meta_field_value;
28use crate::cassandra_sys::cass_iterator_get_table_meta;
29use crate::cassandra_sys::cass_iterator_get_user_type_field_name;
30use crate::cassandra_sys::cass_iterator_get_user_type_field_value;
31use crate::cassandra_sys::cass_iterator_get_value;
32use crate::cassandra_sys::cass_iterator_next;
33use crate::cassandra_sys::cass_true;
34use std::{mem, slice, str};
35
36/// Iterates over the  aggregate metadata entries(??)
37#[derive(Debug)]
38pub struct AggregateIterator(*mut _CassIterator);
39
40// The underlying C type has no thread-local state, but does not support access
41// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
42unsafe impl Send for AggregateIterator {}
43
44impl Drop for AggregateIterator {
45    fn drop(&mut self) {
46        unsafe { cass_iterator_free(self.0) }
47    }
48}
49
50impl Iterator for AggregateIterator {
51    type Item = AggregateMeta;
52    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
53        unsafe {
54            match cass_iterator_next(self.0) {
55                cass_false => None,
56                cass_true => {
57                    let field_value = cass_iterator_get_aggregate_meta(self.0);
58                    Some(AggregateMeta::build(field_value))
59                }
60            }
61        }
62    }
63}
64
65/// Iterater over the fields of a UDT
66#[derive(Debug)]
67pub struct UserTypeIterator(*mut _CassIterator);
68
69// The underlying C type has no thread-local state, but does not support access
70// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
71unsafe impl Send for UserTypeIterator {}
72
73impl Drop for UserTypeIterator {
74    fn drop(&mut self) {
75        unsafe { cass_iterator_free(self.0) }
76    }
77}
78
79impl Iterator for UserTypeIterator {
80    type Item = (String, Value);
81    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
82        unsafe {
83            match cass_iterator_next(self.0) {
84                cass_false => None,
85                cass_true => Some((self.get_field_name(), self.get_field_value())),
86            }
87        }
88    }
89}
90
91impl UserTypeIterator {
92    fn get_field_name(&mut self) -> String {
93        unsafe {
94            let mut name = mem::zeroed();
95            let mut name_length = mem::zeroed();
96            cass_iterator_get_user_type_field_name(self.0, &mut name, &mut name_length)
97                .to_result(())
98                .and_then(|_| {
99                    let slice = slice::from_raw_parts(name as *const u8, name_length as usize);
100                    let name = str::from_utf8(slice)?.to_owned();
101                    Ok(name)
102                })
103                .expect("Cassandra error during iteration")
104        }
105    }
106    fn get_field_value(&mut self) -> Value {
107        unsafe { Value::build(cass_iterator_get_user_type_field_value(self.0)) }
108    }
109}
110
111/// Iterater over the  function metadata entries(??)
112#[derive(Debug)]
113pub struct FunctionIterator(*mut _CassIterator);
114
115// The underlying C type has no thread-local state, but does not support access
116// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
117unsafe impl Send for FunctionIterator {}
118
119impl Iterator for FunctionIterator {
120    type Item = FunctionMeta;
121    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
122        unsafe {
123            match cass_iterator_next(self.0) {
124                cass_false => None,
125                cass_true => Some(FunctionMeta::build(cass_iterator_get_function_meta(self.0))),
126            }
127        }
128    }
129}
130
131/// Iterater over the table's metadata entries(??)
132#[derive(Debug)]
133pub struct TableIterator(*mut _CassIterator);
134
135// The underlying C type has no thread-local state, but does not support access
136// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
137unsafe impl Send for TableIterator {}
138
139impl Iterator for TableIterator {
140    type Item = TableMeta;
141    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
142        unsafe {
143            match cass_iterator_next(self.0) {
144                cass_false => None,
145                cass_true => Some(TableMeta::build(cass_iterator_get_table_meta(self.0))),
146            }
147        }
148    }
149}
150
151/// Iterater over the keyspaces's materialized views
152#[derive(Debug)]
153pub struct MaterializedViewIterator(*mut _CassIterator);
154
155// The underlying C type has no thread-local state, but does not support access
156// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
157unsafe impl Send for MaterializedViewIterator {}
158
159impl Iterator for MaterializedViewIterator {
160    type Item = MaterializedViewMeta;
161    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
162        unsafe {
163            match cass_iterator_next(self.0) {
164                cass_false => None,
165                cass_true => Some(MaterializedViewMeta::build(
166                    cass_iterator_get_materialized_view_meta(self.0),
167                )),
168            }
169        }
170    }
171}
172
173/// Iterater over the keyspace's metadata entries(??)
174#[derive(Debug)]
175pub struct KeyspaceIterator(*mut _CassIterator);
176
177// The underlying C type has no thread-local state, but does not support access
178// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
179unsafe impl Send for KeyspaceIterator {}
180
181impl Iterator for KeyspaceIterator {
182    type Item = KeyspaceMeta;
183    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
184        unsafe {
185            match cass_iterator_next(self.0) {
186                cass_false => None,
187                cass_true => Some(KeyspaceMeta::build(cass_iterator_get_keyspace_meta(self.0))),
188            }
189        }
190    }
191}
192
193/// Iterater over the columns's metadata entries(??)
194#[derive(Debug)]
195pub struct ColumnIterator(*mut _CassIterator);
196
197// The underlying C type has no thread-local state, but does not support access
198// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
199unsafe impl Send for ColumnIterator {}
200
201impl Iterator for ColumnIterator {
202    type Item = ColumnMeta;
203    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
204        unsafe {
205            match cass_iterator_next(self.0) {
206                cass_false => None,
207                cass_true => Some(ColumnMeta::build(cass_iterator_get_column_meta(self.0))),
208            }
209        }
210    }
211}
212
213/// Iterater over the field's metadata entries(??)
214#[derive(Debug)]
215pub struct FieldIterator(*mut _CassIterator);
216
217// The underlying C type has no thread-local state, but does not support access
218// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
219unsafe impl Send for FieldIterator {}
220
221impl Iterator for FieldIterator {
222    type Item = Field;
223    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
224        unsafe {
225            match cass_iterator_next(self.0) {
226                cass_false => None,
227                cass_true => {
228                    let mut name = mem::zeroed();
229                    let mut name_length = mem::zeroed();
230                    cass_iterator_get_meta_field_name(self.0, &mut name, &mut name_length)
231                        .to_result(())
232                        .and_then(|_| {
233                            let slice =
234                                slice::from_raw_parts(name as *const u8, name_length as usize);
235                            let name = str::from_utf8(slice)?.to_owned();
236                            let value = Value::build(cass_iterator_get_meta_field_value(self.0));
237                            Ok(Some(Field { name, value }))
238                        })
239                }
240                .expect("Cassandra error during iteration"),
241            }
242        }
243    }
244}
245
246// pub struct CassIteratorType(_CassIteratorType);
247
248// impl CassIteratorType {
249//    pub fn new(_type: _CassIteratorType) -> Self { CassIteratorType(_type) }
250// }
251
252// impl Protected<*mut _Batch> for CassIterator {
253//    fn inner(&self) -> *mut _CassIterator {
254//        self.0
255//    }
256//    fn build(inner: *mut _CassIterator) -> Self {
257//        CassIterator(inner)
258//    }
259// }
260
261impl ProtectedInner<*mut _CassIterator> for UserTypeIterator {
262    fn inner(&self) -> *mut _CassIterator {
263        self.0
264    }
265}
266
267impl Protected<*mut _CassIterator> for UserTypeIterator {
268    fn build(inner: *mut _CassIterator) -> Self {
269        if inner.is_null() {
270            panic!("Unexpected null pointer")
271        };
272        UserTypeIterator(inner)
273    }
274}
275
276impl ProtectedInner<*mut _CassIterator> for AggregateIterator {
277    fn inner(&self) -> *mut _CassIterator {
278        self.0
279    }
280}
281
282impl Protected<*mut _CassIterator> for AggregateIterator {
283    fn build(inner: *mut _CassIterator) -> Self {
284        if inner.is_null() {
285            panic!("Unexpected null pointer")
286        };
287        AggregateIterator(inner)
288    }
289}
290
291impl ProtectedInner<*mut _CassIterator> for FunctionIterator {
292    fn inner(&self) -> *mut _CassIterator {
293        self.0
294    }
295}
296
297impl Protected<*mut _CassIterator> for FunctionIterator {
298    fn build(inner: *mut _CassIterator) -> Self {
299        if inner.is_null() {
300            panic!("Unexpected null pointer")
301        };
302        FunctionIterator(inner)
303    }
304}
305
306impl ProtectedInner<*mut _CassIterator> for KeyspaceIterator {
307    fn inner(&self) -> *mut _CassIterator {
308        self.0
309    }
310}
311
312impl Protected<*mut _CassIterator> for KeyspaceIterator {
313    fn build(inner: *mut _CassIterator) -> Self {
314        if inner.is_null() {
315            panic!("Unexpected null pointer")
316        };
317        KeyspaceIterator(inner)
318    }
319}
320
321impl ProtectedInner<*mut _CassIterator> for FieldIterator {
322    fn inner(&self) -> *mut _CassIterator {
323        self.0
324    }
325}
326impl Protected<*mut _CassIterator> for FieldIterator {
327    fn build(inner: *mut _CassIterator) -> Self {
328        if inner.is_null() {
329            panic!("Unexpected null pointer")
330        };
331        FieldIterator(inner)
332    }
333}
334
335impl ProtectedInner<*mut _CassIterator> for ColumnIterator {
336    fn inner(&self) -> *mut _CassIterator {
337        self.0
338    }
339}
340
341impl Protected<*mut _CassIterator> for ColumnIterator {
342    fn build(inner: *mut _CassIterator) -> Self {
343        if inner.is_null() {
344            panic!("Unexpected null pointer")
345        };
346        ColumnIterator(inner)
347    }
348}
349
350impl ProtectedInner<*mut _CassIterator> for TableIterator {
351    fn inner(&self) -> *mut _CassIterator {
352        self.0
353    }
354}
355
356impl Protected<*mut _CassIterator> for TableIterator {
357    fn build(inner: *mut _CassIterator) -> Self {
358        if inner.is_null() {
359            panic!("Unexpected null pointer")
360        };
361        TableIterator(inner)
362    }
363}
364
365impl ProtectedInner<*mut _CassIterator> for MaterializedViewIterator {
366    fn inner(&self) -> *mut _CassIterator {
367        self.0
368    }
369}
370
371impl Protected<*mut _CassIterator> for MaterializedViewIterator {
372    fn build(inner: *mut _CassIterator) -> Self {
373        if inner.is_null() {
374            panic!("Unexpected null pointer")
375        };
376        MaterializedViewIterator(inner)
377    }
378}
379
380impl ProtectedInner<*mut _CassIterator> for MapIterator {
381    fn inner(&self) -> *mut _CassIterator {
382        self.0
383    }
384}
385
386impl Protected<*mut _CassIterator> for MapIterator {
387    fn build(inner: *mut _CassIterator) -> Self {
388        if inner.is_null() {
389            panic!("Unexpected null pointer")
390        };
391        MapIterator(inner)
392    }
393}
394
395impl ProtectedInner<*mut _CassIterator> for SetIterator {
396    fn inner(&self) -> *mut _CassIterator {
397        self.0
398    }
399}
400
401impl Protected<*mut _CassIterator> for SetIterator {
402    fn build(inner: *mut _CassIterator) -> Self {
403        if inner.is_null() {
404            panic!("Unexpected null pointer")
405        };
406        SetIterator(inner)
407    }
408}
409
410/// Iterater over the set's metadata entries(??)
411#[derive(Debug)]
412pub struct SetIterator(*mut _CassIterator);
413
414// The underlying C type has no thread-local state, but does not support access
415// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
416unsafe impl Send for SetIterator {}
417
418// impl<'a> Display for &'a SetIterator {
419//    fn fmt(&self, f:&mut Formatter) -> fmt::Result {
420//        for item in self {
421//            try!(write!(f, "{}\t", item));
422//        }
423//        Ok(())
424//    }
425// }
426
427impl Drop for SetIterator {
428    fn drop(&mut self) {
429        unsafe { cass_iterator_free(self.0) }
430    }
431}
432
433impl Iterator for SetIterator {
434    type Item = Value;
435
436    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
437        unsafe {
438            match cass_iterator_next(self.0) {
439                cass_false => None,
440                cass_true => Some(self.get_value()),
441            }
442        }
443    }
444}
445
446impl SetIterator {
447    fn get_value(&mut self) -> Value {
448        unsafe { Value::build(cass_iterator_get_value(self.0)) }
449    }
450}
451
452/// An iterator over the k/v pair in the map
453#[derive(Debug)]
454pub struct MapIterator(*mut _CassIterator);
455
456// The underlying C type has no thread-local state, but does not support access
457// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
458unsafe impl Send for MapIterator {}
459
460impl MapIterator {
461    fn get_key(&mut self) -> Value {
462        unsafe { Value::build(cass_iterator_get_map_key(self.0)) }
463    }
464    fn get_value(&mut self) -> Value {
465        unsafe { Value::build(cass_iterator_get_map_value(self.0)) }
466    }
467
468    /// Gets the next k/v pair in the map
469    pub fn get_pair(&mut self) -> (Value, Value) {
470        (self.get_key(), self.get_value())
471    }
472}
473
474/// An iterator over the elements of a Cassandra tuple
475#[derive(Debug)]
476pub struct TupleIterator(pub *mut _CassIterator);
477
478// The underlying C type has no thread-local state, but does not support access
479// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
480unsafe impl Send for TupleIterator {}
481
482impl Drop for TupleIterator {
483    fn drop(&mut self) {
484        unsafe { cass_iterator_free(self.0) }
485    }
486}
487
488impl Iterator for TupleIterator {
489    type Item = Value;
490    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
491        unsafe {
492            match cass_iterator_next(self.0) {
493                cass_false => None,
494                cass_true => Some(self.get_value()),
495            }
496        }
497    }
498}
499
500impl TupleIterator {
501    fn get_value(&mut self) -> Value {
502        unsafe { Value::build(cass_iterator_get_value(self.0)) }
503    }
504}
505
506impl Drop for MapIterator {
507    fn drop(&mut self) {
508        unsafe { cass_iterator_free(self.0) }
509    }
510}
511
512impl Iterator for MapIterator {
513    type Item = (Value, Value);
514    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
515        unsafe {
516            match cass_iterator_next(self.0) {
517                cass_false => None,
518                cass_true => Some(self.get_pair()),
519            }
520        }
521    }
522}