1use crate::cassandra::data_type::ConstDataType;
2use crate::cassandra::error::*;
3use crate::cassandra::inet::Inet;
4use crate::cassandra::iterator::MapIterator;
5use crate::cassandra::iterator::SetIterator;
6use crate::cassandra::iterator::UserTypeIterator;
7use crate::cassandra::util::{Protected, ProtectedInner};
8use crate::cassandra::uuid::Uuid;
9
10use crate::cassandra_sys::cass_collection_append_decimal;
11use crate::cassandra_sys::cass_iterator_fields_from_user_type;
12use crate::cassandra_sys::cass_iterator_from_collection;
13use crate::cassandra_sys::cass_iterator_from_map;
14use crate::cassandra_sys::cass_true;
15use crate::cassandra_sys::cass_value_data_type;
16use crate::cassandra_sys::cass_value_get_bool;
17use crate::cassandra_sys::cass_value_get_bytes;
18use crate::cassandra_sys::cass_value_get_double;
19use crate::cassandra_sys::cass_value_get_float;
20use crate::cassandra_sys::cass_value_get_inet;
21use crate::cassandra_sys::cass_value_get_int16;
22use crate::cassandra_sys::cass_value_get_int32;
23use crate::cassandra_sys::cass_value_get_int64;
24use crate::cassandra_sys::cass_value_get_int8;
25use crate::cassandra_sys::cass_value_get_string;
26use crate::cassandra_sys::cass_value_get_uint32;
27use crate::cassandra_sys::cass_value_get_uuid;
28use crate::cassandra_sys::cass_value_is_collection;
29use crate::cassandra_sys::cass_value_is_null;
30use crate::cassandra_sys::cass_value_item_count;
31use crate::cassandra_sys::cass_value_primary_sub_type;
32use crate::cassandra_sys::cass_value_secondary_sub_type;
33use crate::cassandra_sys::cass_value_type;
34use crate::cassandra_sys::CassValue as _CassValue;
35use crate::cassandra_sys::CassValueType_;
36use crate::cassandra_sys::CASS_ERROR_LIB_INVALID_VALUE_TYPE;
37use crate::cassandra_sys::CASS_ERROR_LIB_NULL_VALUE;
38use crate::cassandra_sys::CASS_VALUE_TYPE_ASCII;
39use crate::cassandra_sys::CASS_VALUE_TYPE_BIGINT;
40use crate::cassandra_sys::CASS_VALUE_TYPE_BLOB;
41use crate::cassandra_sys::CASS_VALUE_TYPE_BOOLEAN;
42use crate::cassandra_sys::CASS_VALUE_TYPE_COUNTER;
43use crate::cassandra_sys::CASS_VALUE_TYPE_CUSTOM;
44use crate::cassandra_sys::CASS_VALUE_TYPE_DATE;
45use crate::cassandra_sys::CASS_VALUE_TYPE_DECIMAL;
46use crate::cassandra_sys::CASS_VALUE_TYPE_DOUBLE;
47use crate::cassandra_sys::CASS_VALUE_TYPE_DURATION;
48use crate::cassandra_sys::CASS_VALUE_TYPE_FLOAT;
49use crate::cassandra_sys::CASS_VALUE_TYPE_INET;
50use crate::cassandra_sys::CASS_VALUE_TYPE_INT;
51use crate::cassandra_sys::CASS_VALUE_TYPE_LAST_ENTRY;
52use crate::cassandra_sys::CASS_VALUE_TYPE_LIST;
53use crate::cassandra_sys::CASS_VALUE_TYPE_MAP;
54use crate::cassandra_sys::CASS_VALUE_TYPE_SET;
55use crate::cassandra_sys::CASS_VALUE_TYPE_SMALL_INT;
56use crate::cassandra_sys::CASS_VALUE_TYPE_TEXT;
57use crate::cassandra_sys::CASS_VALUE_TYPE_TIME;
58use crate::cassandra_sys::CASS_VALUE_TYPE_TIMESTAMP;
59use crate::cassandra_sys::CASS_VALUE_TYPE_TIMEUUID;
60use crate::cassandra_sys::CASS_VALUE_TYPE_TINY_INT;
61use crate::cassandra_sys::CASS_VALUE_TYPE_TUPLE;
62use crate::cassandra_sys::CASS_VALUE_TYPE_UDT;
63use crate::cassandra_sys::CASS_VALUE_TYPE_UNKNOWN;
64use crate::cassandra_sys::CASS_VALUE_TYPE_UUID;
65use crate::cassandra_sys::CASS_VALUE_TYPE_VARCHAR;
66use crate::cassandra_sys::CASS_VALUE_TYPE_VARINT;
67
68use std::ffi::CString;
69use std::fmt;
70use std::fmt::{Debug, Display, Formatter};
71use std::mem;
72use std::ptr;
73use std::slice;
74use std::str;
75
76#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
78#[allow(missing_docs)] #[allow(non_camel_case_types)] pub enum ValueType {
81 UNKNOWN,
82 CUSTOM,
83 ASCII,
84 BIGINT,
85 BLOB,
86 BOOLEAN,
87 COUNTER,
88 DECIMAL,
89 DOUBLE,
90 FLOAT,
91 INT,
92 TEXT,
93 TIMESTAMP,
94 UUID,
95 VARCHAR,
96 VARINT,
97 TIMEUUID,
98 INET,
99 DATE,
100 TIME,
101 SMALL_INT,
102 TINY_INT,
103 DURATION,
104 LIST,
105 MAP,
106 SET,
107 UDT,
108 TUPLE,
109}
110
111enhance_nullary_enum!(ValueType, CassValueType_, {
112 (UNKNOWN, CASS_VALUE_TYPE_UNKNOWN, "UNKNOWN"),
113 (CUSTOM, CASS_VALUE_TYPE_CUSTOM, "CUSTOM"),
114 (ASCII, CASS_VALUE_TYPE_ASCII, "ASCII"),
115 (BIGINT, CASS_VALUE_TYPE_BIGINT, "BIGINT"),
116 (BLOB, CASS_VALUE_TYPE_BLOB, "BLOB"),
117 (BOOLEAN, CASS_VALUE_TYPE_BOOLEAN, "BOOLEAN"),
118 (COUNTER, CASS_VALUE_TYPE_COUNTER, "COUNTER"),
119 (DECIMAL, CASS_VALUE_TYPE_DECIMAL, "DECIMAL"),
120 (DOUBLE, CASS_VALUE_TYPE_DOUBLE, "DOUBLE"),
121 (FLOAT, CASS_VALUE_TYPE_FLOAT, "FLOAT"),
122 (INT, CASS_VALUE_TYPE_INT, "INT"),
123 (TEXT, CASS_VALUE_TYPE_TEXT, "TEXT"),
124 (TIMESTAMP, CASS_VALUE_TYPE_TIMESTAMP, "TIMESTAMP"),
125 (UUID, CASS_VALUE_TYPE_UUID, "UUID"),
126 (VARCHAR, CASS_VALUE_TYPE_VARCHAR, "VARCHAR"),
127 (VARINT, CASS_VALUE_TYPE_VARINT, "VARINT"),
128 (TIMEUUID, CASS_VALUE_TYPE_TIMEUUID, "TIMEUUID"),
129 (INET, CASS_VALUE_TYPE_INET, "INET"),
130 (DATE, CASS_VALUE_TYPE_DATE, "DATE"),
131 (TIME, CASS_VALUE_TYPE_TIME, "TIME"),
132 (SMALL_INT, CASS_VALUE_TYPE_SMALL_INT, "SMALL_INT"),
133 (TINY_INT, CASS_VALUE_TYPE_TINY_INT, "TINY_INT"),
134 (DURATION, CASS_VALUE_TYPE_DURATION, "DURATION"),
135 (LIST, CASS_VALUE_TYPE_LIST, "LIST"),
136 (MAP, CASS_VALUE_TYPE_MAP, "MAP"),
137 (SET, CASS_VALUE_TYPE_SET, "SET"),
138 (UDT, CASS_VALUE_TYPE_UDT, "UDT"),
139 (TUPLE, CASS_VALUE_TYPE_TUPLE, "TUPLE"),
140}, omit { CASS_VALUE_TYPE_LAST_ENTRY });
141
142pub struct Value(*const _CassValue);
144
145unsafe impl Send for Value {}
147unsafe impl Sync for Value {}
148
149impl ProtectedInner<*const _CassValue> for Value {
150 fn inner(&self) -> *const _CassValue {
151 self.0
152 }
153}
154
155impl Protected<*const _CassValue> for Value {
156 fn build(inner: *const _CassValue) -> Self {
157 if inner.is_null() {
158 panic!("Unexpected null pointer")
159 };
160 Value(inner)
161 }
162}
163
164pub(crate) fn write_set<F>(f: &mut Formatter, set: Result<SetIterator>, writer: F) -> fmt::Result
166where
167 F: Fn(&mut Formatter, Value) -> fmt::Result,
168{
169 write!(f, "[")?;
170 match set {
171 Err(_) => write!(f, "<error>")?,
172 Ok(iter) => {
173 for item in iter {
174 writer(f, item)?
175 }
176 }
177 }
178 write!(f, "]")?;
179 Ok(())
180}
181
182pub(crate) fn write_map<F>(f: &mut Formatter, set: Result<MapIterator>, writer: F) -> fmt::Result
184where
185 F: Fn(&mut Formatter, Value, Value) -> fmt::Result,
186{
187 write!(f, "{{")?;
188 match set {
189 Err(_) => write!(f, "<error>")?,
190 Ok(iter) => {
191 for item in iter {
192 writer(f, item.0, item.1)?
193 }
194 }
195 }
196 write!(f, "}}")?;
197 Ok(())
198}
199
200pub(crate) fn write_value<T, F>(f: &mut Formatter, v: Result<T>, writer: F) -> fmt::Result
201where
202 F: Fn(&mut Formatter, T) -> fmt::Result,
203{
204 match v {
205 Err(_) => write!(f, "<error>"),
206 Ok(v) => writer(f, v),
207 }
208}
209
210impl Debug for Value {
211 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
212 if self.is_null() {
213 Ok(())
214 } else {
215 match self.get_type() {
216 ValueType::UNKNOWN => write!(f, "<unknown>"),
217 ValueType::CUSTOM => write!(f, "<custom>"),
218 ValueType::ASCII | ValueType::TEXT | ValueType::VARCHAR => {
219 write_value(f, self.get_string(), |f, v| write!(f, "{:?}", v))
220 }
221 ValueType::DECIMAL => write_value(f, self.get_bytes(), |f, v| write!(f, "{:?}", v)),
222 ValueType::COUNTER => write_value(f, self.get_i64(), |f, v| write!(f, "{:?}", v)),
223 ValueType::BIGINT => write_value(f, self.get_i64(), |f, v| write!(f, "{:?}", v)),
224 ValueType::DATE => write_value(f, self.get_string(), |f, v| write!(f, "{:?}", v)),
225 ValueType::TIME => write_value(f, self.get_string(), |f, v| write!(f, "{:?}", v)),
226 ValueType::VARINT => write_value(f, self.get_bytes(), |f, v| write!(f, "{:?}", v)),
227 ValueType::BOOLEAN => write_value(f, self.get_bool(), |f, v| write!(f, "{:?}", v)),
228 ValueType::DOUBLE => write_value(f, self.get_f64(), |f, v| write!(f, "{:?}", v)),
229 ValueType::FLOAT => write_value(f, self.get_f32(), |f, v| write!(f, "{:?}", v)),
230 ValueType::BLOB => write_value(f, self.get_bytes(), |f, v| write!(f, "{:?}", v)),
231 ValueType::INT => write_value(f, self.get_i32(), |f, v| write!(f, "{:?}", v)),
232 ValueType::SMALL_INT => write_value(f, self.get_i16(), |f, v| write!(f, "{:?}", v)),
233 ValueType::TINY_INT => write_value(f, self.get_i8(), |f, v| write!(f, "{:?}", v)),
234 ValueType::DURATION => write_value(f, self.get_i32(), |f, v| write!(f, "{:?}", v)),
235 ValueType::INET => write_value(f, self.get_inet(), |f, v| write!(f, "{:?}", v)),
236 ValueType::TIMESTAMP => write_value(f, self.get_i64(), |f, v| write!(f, "{:?}", v)),
237 ValueType::TIMEUUID => {
238 write_value(f, self.get_uuid(), |f, v| write!(f, "TIMEUUID: {}", v))
239 }
240 ValueType::UUID => write_value(f, self.get_uuid(), |f, v| write!(f, "UUID: {}", v)),
241 ValueType::SET | ValueType::LIST => {
242 write_set(f, self.get_set(), |f, i| write!(f, "{:?}, ", i))
243 }
244 ValueType::MAP => write_map(f, self.get_map(), |f, k, v| {
245 write!(f, "{:?} => {:?}, ", k, v)
246 }),
247 ValueType::UDT => write!(f, "<udt>"),
248 ValueType::TUPLE => write_set(f, self.get_set(), |f, i| write!(f, "{:?}, ", i)),
249 }
250 }
251 }
252}
253
254impl Display for Value {
255 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
256 if self.is_null() {
257 Ok(())
258 } else {
259 match self.get_type() {
260 ValueType::UNKNOWN => write!(f, "{}", "unknown"),
261 ValueType::CUSTOM => write!(f, "{}", "custom"),
262 ValueType::ASCII | ValueType::TEXT | ValueType::VARCHAR => {
263 write_value(f, self.get_string(), |f, v| write!(f, "{}", v))
264 }
265 ValueType::DECIMAL => {
266 write_value(f, self.get_bytes(), |f, v| write!(f, "DECIMAL:{:?}", v))
267 }
268 ValueType::COUNTER => write_value(f, self.get_i64(), |f, v| write!(f, "{}", v)),
269 ValueType::BIGINT => write_value(f, self.get_i64(), |f, v| write!(f, "{}", v)),
270 ValueType::DATE => write_value(f, self.get_string(), |f, v| write!(f, "{}", v)),
271 ValueType::TIME => write_value(f, self.get_string(), |f, v| write!(f, "{}", v)),
272 ValueType::VARINT => {
273 write_value(f, self.get_bytes(), |f, v| write!(f, "VARINT:{:?}", v))
274 }
275 ValueType::BOOLEAN => write_value(f, self.get_bool(), |f, v| write!(f, "{}", v)),
276 ValueType::DOUBLE => write_value(f, self.get_f64(), |f, v| write!(f, "{}", v)),
277 ValueType::FLOAT => write_value(f, self.get_f32(), |f, v| write!(f, "{}", v)),
278 ValueType::BLOB => {
279 write_value(f, self.get_bytes(), |f, v| write!(f, "BLOB:{:?}", v))
280 }
281 ValueType::INT => write_value(f, self.get_i32(), |f, v| write!(f, "{}", v)),
282 ValueType::SMALL_INT => write_value(f, self.get_i16(), |f, v| write!(f, "{}", v)),
283 ValueType::TINY_INT => write_value(f, self.get_i8(), |f, v| write!(f, "{}", v)),
284 ValueType::DURATION => write_value(f, self.get_i32(), |f, v| write!(f, "{:?}", v)),
285 ValueType::INET => {
286 write_value(f, self.get_inet(), |f, v| write!(f, "INET:{:?}", v))
287 }
288 ValueType::TIMESTAMP => write_value(f, self.get_i64(), |f, v| write!(f, "{}", v)),
289 ValueType::TIMEUUID => {
290 write_value(f, self.get_uuid(), |f, v| write!(f, "TIMEUUID:{}", v))
291 }
292 ValueType::UUID => write_value(f, self.get_uuid(), |f, v| write!(f, "UUID:{}", v)),
293 ValueType::SET | ValueType::LIST => {
294 write_set(f, self.get_set(), |f, i| write!(f, "{}, ", i))
295 }
296 ValueType::MAP => {
297 write_map(f, self.get_map(), |f, k, v| write!(f, "{} => {}, ", k, v))
298 }
299 ValueType::UDT => write!(f, "<udt>"),
300 ValueType::TUPLE => write_set(f, self.get_set(), |f, i| write!(f, "{}, ", i)),
301 }
302 }
303 }
304}
305
306impl Value {
307 pub fn get_bytes(&self) -> Result<&[u8]> {
309 unsafe {
310 let mut output = mem::zeroed();
311 let mut output_size = mem::zeroed();
312 let result = cass_value_get_bytes(self.0, &mut output, &mut output_size);
313 let slice = slice::from_raw_parts(output, output_size as usize);
315 result.to_result(slice)
316 }
317 }
318 pub fn get_type(&self) -> ValueType {
326 unsafe { ValueType::build(cass_value_type(self.0)) }
327 }
328
329 pub fn data_type(&self) -> ConstDataType {
331 unsafe { ConstDataType::build(cass_value_data_type(self.0)) }
332 }
333
334 pub fn is_null(&self) -> bool {
336 unsafe { cass_value_is_null(self.0) == cass_true }
337 }
338
339 pub fn is_collection(&self) -> bool {
341 unsafe { cass_value_is_collection(self.0) == cass_true }
342 }
343
344 pub fn get_set(&self) -> Result<SetIterator> {
361 unsafe {
362 match self.get_type() {
363 ValueType::SET | ValueType::LIST | ValueType::TUPLE => {
364 let iter = cass_iterator_from_collection(self.0);
365 if iter.is_null() {
366 Err(CASS_ERROR_LIB_NULL_VALUE.to_error())
368 } else {
369 Ok(SetIterator::build(iter))
370 }
371 }
372 _ => Err(CASS_ERROR_LIB_INVALID_VALUE_TYPE.to_error()),
373 }
374 }
375 }
376
377 pub fn get_map(&self) -> Result<MapIterator> {
379 unsafe {
380 match self.get_type() {
381 ValueType::MAP => {
382 let iter = cass_iterator_from_map(self.0);
383 if iter.is_null() {
384 Err(CASS_ERROR_LIB_NULL_VALUE.to_error())
386 } else {
387 Ok(MapIterator::build(iter))
388 }
389 }
390 _ => Err(CASS_ERROR_LIB_INVALID_VALUE_TYPE.to_error()),
391 }
392 }
393 }
394
395 pub fn get_user_type(&self) -> Result<UserTypeIterator> {
397 unsafe {
398 match self.get_type() {
399 ValueType::UDT => {
400 let iter = cass_iterator_fields_from_user_type(self.0);
401 if iter.is_null() {
402 Err(CASS_ERROR_LIB_NULL_VALUE.to_error())
404 } else {
405 Ok(UserTypeIterator::build(iter))
406 }
407 }
408 _ => Err(CASS_ERROR_LIB_INVALID_VALUE_TYPE.to_error()),
409 }
410 }
411 }
412
413 pub fn get_str(&self) -> Result<&str> {
415 unsafe {
416 let mut message_ptr = mem::zeroed();
417 let mut message_length = mem::zeroed();
418 cass_value_get_string(self.0, &mut message_ptr, &mut message_length)
419 .to_result(())
420 .and_then(|_| {
421 let slice =
422 slice::from_raw_parts(message_ptr as *const u8, message_length as usize);
423 Ok(str::from_utf8(slice)?)
424 })
425 }
426 }
427
428 pub fn get_string(&self) -> Result<String> {
430 self.get_str().map(str::to_string)
431 }
432
433 pub fn get_inet(&self) -> Result<Inet> {
435 unsafe {
436 let mut inet = mem::zeroed();
437 cass_value_get_inet(self.0, &mut inet).to_result(Inet::build(inet))
438 }
439 }
440
441 pub fn get_i32(&self) -> Result<i32> {
443 unsafe {
444 let mut output = mem::zeroed();
445 cass_value_get_int32(self.0, &mut output).to_result(output)
446 }
447 }
448
449 pub fn get_u32(&self) -> Result<u32> {
451 unsafe {
452 let mut output = mem::zeroed();
453 cass_value_get_uint32(self.0, &mut output).to_result(output)
454 }
455 }
456
457 pub fn get_i16(&self) -> Result<i16> {
459 unsafe {
460 let mut output = mem::zeroed();
461 cass_value_get_int16(self.0, &mut output).to_result(output)
462 }
463 }
464
465 pub fn get_i8(&self) -> Result<i8> {
467 unsafe {
468 let mut output = mem::zeroed();
469 cass_value_get_int8(self.0, &mut output).to_result(output)
470 }
471 }
472
473 pub fn get_i64(&self) -> Result<i64> {
475 unsafe {
476 let mut output = mem::zeroed();
477 cass_value_get_int64(self.0, &mut output).to_result(output)
478 }
479 }
480
481 pub fn get_f32(&self) -> Result<f32> {
483 unsafe {
484 let mut output = mem::zeroed();
485 cass_value_get_float(self.0, &mut output).to_result(output)
486 }
487 }
488
489 pub fn get_f64(&self) -> Result<f64> {
491 unsafe {
492 let mut output = mem::zeroed();
493 cass_value_get_double(self.0, &mut output).to_result(output)
494 }
495 }
496
497 pub fn get_bool(&self) -> Result<bool> {
499 unsafe {
500 let mut output = mem::zeroed();
501 cass_value_get_bool(self.0, &mut output).to_result(output == cass_true)
502 }
503 }
504
505 pub fn get_uuid(&self) -> Result<Uuid> {
507 unsafe {
508 let mut uuid = mem::zeroed();
509 cass_value_get_uuid(self.0, &mut uuid).to_result(Uuid::build(uuid))
510 }
511 }
512}