cassandra_cpp/cassandra/
collection.rs

1use crate::cassandra::data_type::ConstDataType;
2use crate::cassandra::data_type::DataType;
3use crate::cassandra::error::*;
4use crate::cassandra::inet::Inet;
5use crate::cassandra::tuple::Tuple;
6use crate::cassandra::user_type::UserType;
7use crate::cassandra::util::{Protected, ProtectedInner};
8use crate::cassandra::uuid::Uuid;
9
10use crate::cassandra_sys::cass_collection_append_bool;
11use crate::cassandra_sys::cass_collection_append_bytes;
12use crate::cassandra_sys::cass_collection_append_collection;
13
14use crate::cassandra_sys::cass_collection_append_double;
15use crate::cassandra_sys::cass_collection_append_float;
16use crate::cassandra_sys::cass_collection_append_inet;
17use crate::cassandra_sys::cass_collection_append_int16;
18use crate::cassandra_sys::cass_collection_append_int32;
19use crate::cassandra_sys::cass_collection_append_int64;
20use crate::cassandra_sys::cass_collection_append_int8;
21use crate::cassandra_sys::cass_collection_append_string_n;
22use crate::cassandra_sys::cass_collection_append_tuple;
23use crate::cassandra_sys::cass_collection_append_uint32;
24use crate::cassandra_sys::cass_collection_append_user_type;
25use crate::cassandra_sys::cass_collection_append_uuid;
26use crate::cassandra_sys::cass_collection_data_type;
27use crate::cassandra_sys::cass_collection_free;
28use crate::cassandra_sys::cass_collection_new;
29use crate::cassandra_sys::cass_collection_new_from_data_type;
30use crate::cassandra_sys::cass_false;
31use crate::cassandra_sys::cass_true;
32use crate::cassandra_sys::CassCollection as _CassCollection;
33use crate::cassandra_sys::CASS_COLLECTION_TYPE_LIST;
34use crate::cassandra_sys::CASS_COLLECTION_TYPE_MAP;
35use crate::cassandra_sys::CASS_COLLECTION_TYPE_SET;
36
37use std::os::raw::c_char;
38
39// #[repr(C)]
40// #[derive(Debug,Copy,Clone)]
41// pub enum CassCollectionType {
42//    CASS_COLLECTION_TYPE_LIST,
43//    CASS_COLLECTION_TYPE_MAP,
44//    CASS_COLLECTION_TYPE_SET,
45// }
46
47/// A generic Cassandra collection that needs to go away
48pub trait CassCollection: Sized {
49    /// The type of value held by this collection
50    type Value;
51
52    /// Creates a new collection.
53    fn new() -> Self {
54        Self::with_capacity(0)
55    }
56
57    /// Creates a new collection, specifying a capacity which will be
58    /// used as a size hint to avoid re-allocations of the collection internally.
59    ///
60    /// If you know the number of items you'll insert into the collection ahead of time,
61    /// it is recommended to use this function over [`CassCollection::new`].
62    fn with_capacity(capacity: usize) -> Self;
63
64    /// Creates a new collection from an existing data type.
65    fn new_from_data_type(value: DataType, item_count: usize) -> Self;
66
67    /// Gets the data type of a collection.
68    fn data_type(&self) -> ConstDataType;
69
70    /// Appends a "tinyint" to the collection.
71    fn append_int8(&mut self, value: i8) -> Result<&mut Self>;
72
73    /// Appends an "smallint" to the collection.
74    fn append_int16(&mut self, value: i16) -> Result<&mut Self>;
75
76    /// Appends an "int" to the collection.
77    fn append_int32(&mut self, value: i32) -> Result<&mut Self>;
78
79    /// Appends a "date" to the collection.
80    fn append_uint32(&mut self, value: u32) -> Result<&mut Self>;
81
82    /// Appends a "bigint", "counter", "timestamp" or "time" to the
83    /// collection.
84    fn append_int64(&mut self, value: i64) -> Result<&mut Self>;
85
86    /// Appends a "float" to the collection.
87    fn append_float(&mut self, value: f32) -> Result<&mut Self>;
88
89    /// Appends a "double" to the collection.
90    fn append_double(&mut self, value: f64) -> Result<&mut Self>;
91
92    /// Appends a "boolean" to the collection.
93    fn append_bool(&mut self, value: bool) -> Result<&mut Self>;
94
95    /// Appends an "ascii", "text" or "varchar" to the collection.
96    fn append_string(&mut self, value: &str) -> Result<&mut Self>;
97
98    /// Appends a "blob", "varint" or "custom" to the collection.
99    fn append_bytes(&mut self, value: Vec<u8>) -> Result<&mut Self>;
100
101    /// Appends a "uuid" or "timeuuid"  to the collection.
102    fn append_uuid(&mut self, value: Uuid) -> Result<&mut Self>;
103
104    /// Appends an "inet" to the collection.
105    fn append_inet(&mut self, value: Inet) -> Result<&mut Self>;
106
107    /// Appends a "list" to the collection.
108    fn append_list(&mut self, value: List) -> Result<&mut Self>;
109
110    /// Appends a "set" to the collection.
111    fn append_set(&mut self, value: Set) -> Result<&mut Self>;
112
113    /// Appends a "map" to the collection.
114    fn append_map(&mut self, value: Map) -> Result<&mut Self>;
115
116    /// Appends a "tuple" to the collection.
117    fn append_tuple(&mut self, value: Tuple) -> Result<&mut Self>;
118
119    /// Appends a "udt" to the collection.
120    fn append_user_type(&mut self, value: &UserType) -> Result<&mut Self>;
121}
122
123/// A cassandra list collection
124#[derive(Debug)]
125pub struct List(*mut _CassCollection);
126
127// The underlying C type has no thread-local state, and forbids only concurrent
128// mutation/free: https://datastax.github.io/cpp-driver/topics/#thread-safety
129unsafe impl Send for List {}
130unsafe impl Sync for List {}
131
132impl ProtectedInner<*mut _CassCollection> for List {
133    fn inner(&self) -> *mut _CassCollection {
134        self.0
135    }
136}
137
138impl Protected<*mut _CassCollection> for List {
139    fn build(inner: *mut _CassCollection) -> Self {
140        if inner.is_null() {
141            panic!("Unexpected null pointer")
142        };
143        List(inner)
144    }
145}
146
147impl ProtectedInner<*mut _CassCollection> for Map {
148    fn inner(&self) -> *mut _CassCollection {
149        self.0
150    }
151}
152
153impl Protected<*mut _CassCollection> for Map {
154    fn build(inner: *mut _CassCollection) -> Self {
155        if inner.is_null() {
156            panic!("Unexpected null pointer")
157        };
158        Map(inner)
159    }
160}
161
162impl ProtectedInner<*mut _CassCollection> for Set {
163    fn inner(&self) -> *mut _CassCollection {
164        self.0
165    }
166}
167
168impl Protected<*mut _CassCollection> for Set {
169    fn build(inner: *mut _CassCollection) -> Self {
170        if inner.is_null() {
171            panic!("Unexpected null pointer")
172        };
173        Set(inner)
174    }
175}
176
177impl Drop for List {
178    fn drop(&mut self) {
179        unsafe { cass_collection_free(self.0) }
180    }
181}
182
183impl CassCollection for List {
184    type Value = _CassCollection;
185
186    /// create a new list
187    fn with_capacity(capacity: usize) -> Self {
188        unsafe { List::build(cass_collection_new(CASS_COLLECTION_TYPE_LIST, capacity)) }
189    }
190
191    fn new_from_data_type(value: DataType, item_count: usize) -> Self {
192        unsafe {
193            List(cass_collection_new_from_data_type(
194                value.inner(),
195                item_count,
196            ))
197        }
198    }
199
200    /// Gets the data type of a collection.
201    fn data_type(&self) -> ConstDataType {
202        unsafe { ConstDataType::build(cass_collection_data_type(self.inner())) }
203    }
204
205    /// Appends a "tinyint" to the collection.
206    fn append_int8(&mut self, value: i8) -> Result<&mut Self> {
207        unsafe { cass_collection_append_int8(self.inner(), value).to_result(self) }
208    }
209
210    /// Appends an "smallint" to the collection.
211    fn append_int16(&mut self, value: i16) -> Result<&mut Self> {
212        unsafe { cass_collection_append_int16(self.inner(), value).to_result(self) }
213    }
214
215    /// Appends an "int" to the collection.
216    fn append_int32(&mut self, value: i32) -> Result<&mut Self> {
217        unsafe { cass_collection_append_int32(self.inner(), value).to_result(self) }
218    }
219
220    /// Appends a "date" to the collection.
221    fn append_uint32(&mut self, value: u32) -> Result<&mut Self> {
222        unsafe { cass_collection_append_uint32(self.inner(), value).to_result(self) }
223    }
224
225    /// Appends a "bigint", "counter", "timestamp" or "time" to the
226    /// collection.
227    fn append_int64(&mut self, value: i64) -> Result<&mut Self> {
228        unsafe { cass_collection_append_int64(self.inner(), value).to_result(self) }
229    }
230
231    /// Appends a "float" to the collection.
232    fn append_float(&mut self, value: f32) -> Result<&mut Self> {
233        unsafe { cass_collection_append_float(self.inner(), value).to_result(self) }
234    }
235
236    /// Appends a "double" to the collection.
237    fn append_double(&mut self, value: f64) -> Result<&mut Self> {
238        unsafe { cass_collection_append_double(self.inner(), value).to_result(self) }
239    }
240
241    /// Appends a "boolean" to the collection.
242    fn append_bool(&mut self, value: bool) -> Result<&mut Self> {
243        unsafe {
244            cass_collection_append_bool(self.inner(), if value { cass_true } else { cass_false })
245                .to_result(self)
246        }
247    }
248
249    /// Appends an "ascii", "text" or "varchar" to the collection.
250    fn append_string(&mut self, value: &str) -> Result<&mut Self> {
251        unsafe {
252            let value_ptr = value.as_ptr() as *const c_char;
253            let result = cass_collection_append_string_n(self.inner(), value_ptr, value.len());
254            result.to_result(self)
255        }
256    }
257
258    /// Appends a "blob", "varint" or "custom" to the collection.
259    fn append_bytes(&mut self, value: Vec<u8>) -> Result<&mut Self> {
260        unsafe {
261            let bytes = cass_collection_append_bytes(self.inner(), value[..].as_ptr(), value.len());
262            bytes.to_result(self)
263        }
264    }
265
266    /// Appends a "uuid" or "timeuuid"  to the collection.
267    fn append_uuid(&mut self, value: Uuid) -> Result<&mut Self> {
268        unsafe { cass_collection_append_uuid(self.inner(), value.inner()).to_result(self) }
269    }
270
271    /// Appends an "inet" to the collection.
272    fn append_inet(&mut self, value: Inet) -> Result<&mut Self> {
273        unsafe { cass_collection_append_inet(self.inner(), value.inner()).to_result(self) }
274    }
275
276    /// Appends a "list" to the collection.
277    fn append_list(&mut self, value: List) -> Result<&mut Self> {
278        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
279    }
280
281    /// Appends a "set" to the collection.
282    fn append_set(&mut self, value: Set) -> Result<&mut Self> {
283        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
284    }
285
286    /// Appends a "map" to the collection.
287    fn append_map(&mut self, value: Map) -> Result<&mut Self> {
288        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
289    }
290
291    /// Appends a "tuple" to the collection.
292    fn append_tuple(&mut self, value: Tuple) -> Result<&mut Self> {
293        unsafe { cass_collection_append_tuple(self.inner(), value.inner()).to_result(self) }
294    }
295
296    /// Appends a "udt" to the collection.
297    fn append_user_type(&mut self, value: &UserType) -> Result<&mut Self> {
298        unsafe { cass_collection_append_user_type(self.inner(), value.inner()).to_result(self) }
299    }
300}
301
302/// A Cassandra set
303#[derive(Debug)]
304pub struct Set(*mut _CassCollection);
305
306// The underlying C type has no thread-local state, and forbids only concurrent
307// mutation/free: https://datastax.github.io/cpp-driver/topics/#thread-safety
308unsafe impl Send for Set {}
309unsafe impl Sync for Set {}
310
311impl Drop for Set {
312    fn drop(&mut self) {
313        unsafe { cass_collection_free(self.inner()) }
314    }
315}
316
317// impl CassIterator for Set{
318//
319// }
320
321impl CassCollection for Set {
322    type Value = _CassCollection;
323
324    /// create a new list
325    fn with_capacity(capacity: usize) -> Self {
326        unsafe { Set(cass_collection_new(CASS_COLLECTION_TYPE_SET, capacity)) }
327    }
328
329    fn new_from_data_type(value: DataType, item_count: usize) -> Self {
330        unsafe {
331            Set(cass_collection_new_from_data_type(
332                value.inner(),
333                item_count,
334            ))
335        }
336    }
337    /// Gets the data type of a collection.
338    fn data_type(&self) -> ConstDataType {
339        unsafe { ConstDataType::build(cass_collection_data_type(self.inner())) }
340    }
341
342    /// Appends a "tinyint" to the collection.
343    fn append_int8(&mut self, value: i8) -> Result<&mut Self> {
344        unsafe { cass_collection_append_int8(self.inner(), value).to_result(self) }
345    }
346
347    /// Appends an "smallint" to the collection.
348    fn append_int16(&mut self, value: i16) -> Result<&mut Self> {
349        unsafe { cass_collection_append_int16(self.inner(), value).to_result(self) }
350    }
351
352    /// Appends an "int" to the collection.
353    fn append_int32(&mut self, value: i32) -> Result<&mut Self> {
354        unsafe { cass_collection_append_int32(self.inner(), value).to_result(self) }
355    }
356
357    /// Appends a "date" to the collection.
358    fn append_uint32(&mut self, value: u32) -> Result<&mut Self> {
359        unsafe { cass_collection_append_uint32(self.inner(), value).to_result(self) }
360    }
361
362    /// Appends a "bigint", "counter", "timestamp" or "time" to the
363    /// collection.
364    fn append_int64(&mut self, value: i64) -> Result<&mut Self> {
365        unsafe { cass_collection_append_int64(self.inner(), value).to_result(self) }
366    }
367
368    /// Appends a "float" to the collection.
369    fn append_float(&mut self, value: f32) -> Result<&mut Self> {
370        unsafe { cass_collection_append_float(self.inner(), value).to_result(self) }
371    }
372
373    /// Appends a "double" to the collection.
374    fn append_double(&mut self, value: f64) -> Result<&mut Self> {
375        unsafe { cass_collection_append_double(self.inner(), value).to_result(self) }
376    }
377
378    /// Appends a "boolean" to the collection.
379    fn append_bool(&mut self, value: bool) -> Result<&mut Self> {
380        unsafe {
381            cass_collection_append_bool(self.inner(), if value { cass_true } else { cass_false })
382                .to_result(self)
383        }
384    }
385
386    /// Appends an "ascii", "text" or "varchar" to the collection.
387    fn append_string(&mut self, value: &str) -> Result<&mut Self> {
388        unsafe {
389            let value_ptr = value.as_ptr() as *const c_char;
390            let result = cass_collection_append_string_n(self.inner(), value_ptr, value.len());
391            result.to_result(self)
392        }
393    }
394
395    /// Appends a "blob", "varint" or "custom" to the collection.
396    fn append_bytes(&mut self, value: Vec<u8>) -> Result<&mut Self> {
397        unsafe {
398            let bytes = cass_collection_append_bytes(self.inner(), value[..].as_ptr(), value.len());
399            bytes.to_result(self)
400        }
401    }
402
403    /// Appends a "uuid" or "timeuuid"  to the collection.
404    fn append_uuid(&mut self, value: Uuid) -> Result<&mut Self> {
405        unsafe { cass_collection_append_uuid(self.inner(), value.inner()).to_result(self) }
406    }
407
408    /// Appends an "inet" to the collection.
409    fn append_inet(&mut self, value: Inet) -> Result<&mut Self> {
410        unsafe { cass_collection_append_inet(self.inner(), value.inner()).to_result(self) }
411    }
412
413    /// Appends a "list" to the collection.
414    fn append_list(&mut self, value: List) -> Result<&mut Self> {
415        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
416    }
417
418    /// Appends a "set" to the collection.
419    fn append_set(&mut self, value: Set) -> Result<&mut Self> {
420        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
421    }
422
423    /// Appends a "map" to the collection.
424    fn append_map(&mut self, value: Map) -> Result<&mut Self> {
425        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
426    }
427
428    /// Appends a "tuple" to the collection.
429    fn append_tuple(&mut self, value: Tuple) -> Result<&mut Self> {
430        unsafe { cass_collection_append_tuple(self.inner(), value.inner()).to_result(self) }
431    }
432
433    /// Appends a "udt" to the collection.
434    fn append_user_type(&mut self, value: &UserType) -> Result<&mut Self> {
435        unsafe { cass_collection_append_user_type(self.inner(), value.inner()).to_result(self) }
436    }
437}
438
439/// A Cassandra Map
440#[derive(Debug)]
441pub struct Map(*mut _CassCollection);
442
443// The underlying C type has no thread-local state, and forbids only concurrent
444// mutation/free: https://datastax.github.io/cpp-driver/topics/#thread-safety
445unsafe impl Send for Map {}
446unsafe impl Sync for Map {}
447
448impl Drop for Map {
449    fn drop(&mut self) {
450        unsafe { cass_collection_free(self.0) }
451    }
452}
453
454impl CassCollection for Map {
455    type Value = _CassCollection;
456
457    fn with_capacity(capacity: usize) -> Self {
458        unsafe { Map(cass_collection_new(CASS_COLLECTION_TYPE_MAP, capacity)) }
459    }
460
461    fn new_from_data_type(value: DataType, item_count: usize) -> Self {
462        unsafe {
463            Map(cass_collection_new_from_data_type(
464                value.inner(),
465                item_count,
466            ))
467        }
468    }
469
470    /// Gets the data type of a collection.
471    fn data_type(&self) -> ConstDataType {
472        unsafe { ConstDataType::build(cass_collection_data_type(self.inner())) }
473    }
474
475    /// Appends a "tinyint" to the collection.
476    fn append_int8(&mut self, value: i8) -> Result<&mut Self> {
477        unsafe { cass_collection_append_int8(self.inner(), value).to_result(self) }
478    }
479
480    /// Appends an "smallint" to the collection.
481    fn append_int16(&mut self, value: i16) -> Result<&mut Self> {
482        unsafe { cass_collection_append_int16(self.inner(), value).to_result(self) }
483    }
484
485    /// Appends an "int" to the collection.
486    fn append_int32(&mut self, value: i32) -> Result<&mut Self> {
487        unsafe { cass_collection_append_int32(self.inner(), value).to_result(self) }
488    }
489
490    /// Appends a "date" to the collection.
491    fn append_uint32(&mut self, value: u32) -> Result<&mut Self> {
492        unsafe { cass_collection_append_uint32(self.inner(), value).to_result(self) }
493    }
494
495    /// Appends a "bigint", "counter", "timestamp" or "time" to the
496    /// collection.
497    fn append_int64(&mut self, value: i64) -> Result<&mut Self> {
498        unsafe { cass_collection_append_int64(self.inner(), value).to_result(self) }
499    }
500
501    /// Appends a "float" to the collection.
502    fn append_float(&mut self, value: f32) -> Result<&mut Self> {
503        unsafe { cass_collection_append_float(self.inner(), value).to_result(self) }
504    }
505
506    /// Appends a "double" to the collection.
507    fn append_double(&mut self, value: f64) -> Result<&mut Self> {
508        unsafe { cass_collection_append_double(self.inner(), value).to_result(self) }
509    }
510
511    /// Appends a "boolean" to the collection.
512    fn append_bool(&mut self, value: bool) -> Result<&mut Self> {
513        unsafe {
514            cass_collection_append_bool(self.inner(), if value { cass_true } else { cass_false })
515                .to_result(self)
516        }
517    }
518
519    /// Appends an "ascii", "text" or "varchar" to the collection.
520    fn append_string(&mut self, value: &str) -> Result<&mut Self> {
521        unsafe {
522            let value_ptr = value.as_ptr() as *const c_char;
523            let result = cass_collection_append_string_n(self.inner(), value_ptr, value.len());
524            result.to_result(self)
525        }
526    }
527
528    /// Appends a "blob", "varint" or "custom" to the collection.
529    fn append_bytes(&mut self, value: Vec<u8>) -> Result<&mut Self> {
530        unsafe {
531            let bytes = cass_collection_append_bytes(self.inner(), value[..].as_ptr(), value.len());
532            bytes.to_result(self)
533        }
534    }
535
536    /// Appends a "uuid" or "timeuuid"  to the collection.
537    fn append_uuid(&mut self, value: Uuid) -> Result<&mut Self> {
538        unsafe { cass_collection_append_uuid(self.inner(), value.inner()).to_result(self) }
539    }
540
541    /// Appends an "inet" to the collection.
542    fn append_inet(&mut self, value: Inet) -> Result<&mut Self> {
543        unsafe { cass_collection_append_inet(self.inner(), value.inner()).to_result(self) }
544    }
545
546    /// Appends a "list" to the collection.
547    fn append_list(&mut self, value: List) -> Result<&mut Self> {
548        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
549    }
550
551    /// Appends a "set" to the collection.
552    fn append_set(&mut self, value: Set) -> Result<&mut Self> {
553        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
554    }
555
556    /// Appends a "map" to the collection.
557    fn append_map(&mut self, value: Map) -> Result<&mut Self> {
558        unsafe { cass_collection_append_collection(self.inner(), value.0).to_result(self) }
559    }
560
561    /// Appends a "tuple" to the collection.
562    fn append_tuple(&mut self, value: Tuple) -> Result<&mut Self> {
563        unsafe { cass_collection_append_tuple(self.inner(), value.inner()).to_result(self) }
564    }
565
566    /// Appends a "udt" to the collection.
567    fn append_user_type(&mut self, value: &UserType) -> Result<&mut Self> {
568        unsafe { cass_collection_append_user_type(self.inner(), value.inner()).to_result(self) }
569    }
570}