1use integer_encoding::VarInt;
2use num_bigint::BigInt;
3use std::convert::TryInto;
4use std::io;
5use std::net;
6use std::string::FromUtf8Error;
7
8use super::blob::Blob;
9use super::decimal::Decimal;
10use super::duration::Duration;
11use crate::error;
12use crate::frame::{FromCursor, Version};
13use crate::types::{
14 try_f32_from_bytes, try_f64_from_bytes, try_i16_from_bytes, try_i32_from_bytes,
15 try_i64_from_bytes, CBytes, CInt, INT_LEN,
16};
17
18const FALSE_BYTE: u8 = 0;
21
22#[inline]
24pub fn decode_custom(bytes: &[u8]) -> Result<String, FromUtf8Error> {
25 Ok(String::from_utf8_lossy(bytes).into_owned())
26}
27
28#[inline]
30pub fn decode_ascii(bytes: &[u8]) -> Result<String, FromUtf8Error> {
31 Ok(String::from_utf8_lossy(bytes).into_owned())
32}
33
34#[inline]
36pub fn decode_varchar(bytes: &[u8]) -> Result<String, FromUtf8Error> {
37 Ok(String::from_utf8_lossy(bytes).into_owned())
38}
39
40#[inline]
42pub fn decode_bigint(bytes: &[u8]) -> Result<i64, io::Error> {
43 try_i64_from_bytes(bytes)
44}
45
46#[inline]
48pub fn decode_blob(bytes: &[u8]) -> Result<Blob, io::Error> {
49 Ok(bytes.into())
51}
52
53#[inline]
55pub fn decode_boolean(bytes: &[u8]) -> Result<bool, io::Error> {
56 if bytes.is_empty() {
57 Err(io::Error::new(
58 io::ErrorKind::UnexpectedEof,
59 "no bytes were found",
60 ))
61 } else {
62 Ok(bytes[0] != FALSE_BYTE)
63 }
64}
65
66#[inline]
68pub fn decode_int(bytes: &[u8]) -> Result<i32, io::Error> {
69 try_i32_from_bytes(bytes)
70}
71
72#[inline]
77pub fn decode_date(bytes: &[u8]) -> Result<i32, io::Error> {
78 try_i32_from_bytes(bytes)
79}
80
81pub fn decode_decimal(bytes: &[u8]) -> Result<Decimal, io::Error> {
83 let lr = bytes.split_at(INT_LEN);
84
85 let scale = try_i32_from_bytes(lr.0)?;
86 let unscaled = decode_varint(lr.1)?;
87
88 Ok(Decimal::new(unscaled, scale))
89}
90
91#[inline]
93pub fn decode_double(bytes: &[u8]) -> Result<f64, io::Error> {
94 try_f64_from_bytes(bytes)
95}
96
97#[inline]
99pub fn decode_float(bytes: &[u8]) -> Result<f32, io::Error> {
100 try_f32_from_bytes(bytes)
101}
102
103#[allow(clippy::many_single_char_names)]
105pub fn decode_inet(bytes: &[u8]) -> Result<net::IpAddr, io::Error> {
106 match bytes.len() {
107 4 => {
109 let array: [u8; 4] = bytes[0..4].try_into().unwrap();
110 Ok(net::IpAddr::V4(net::Ipv4Addr::from(array)))
111 }
112 16 => {
114 let array: [u8; 16] = bytes[0..16].try_into().unwrap();
115 Ok(net::IpAddr::V6(net::Ipv6Addr::from(array)))
116 }
117 _ => Err(io::Error::new(
118 io::ErrorKind::Other,
119 format!("Invalid Ip address {bytes:?}"),
120 )),
121 }
122}
123
124#[inline]
129pub fn decode_timestamp(bytes: &[u8]) -> Result<i64, io::Error> {
130 try_i64_from_bytes(bytes)
131}
132
133pub fn decode_list(bytes: &[u8], version: Version) -> Result<Vec<CBytes>, io::Error> {
136 let mut cursor = io::Cursor::new(bytes);
137 let l = CInt::from_cursor(&mut cursor, version)
138 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
139 let mut list = Vec::with_capacity(l as usize);
140 for _ in 0..l {
141 let b = CBytes::from_cursor(&mut cursor, version)
142 .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
143 list.push(b);
144 }
145 Ok(list)
146}
147
148pub fn decode_float_vector(
149 bytes: &[u8],
150 _version: Version,
151 count: usize,
152) -> Result<Vec<CBytes>, io::Error> {
153 let type_size = 4;
154
155 let mut vector = Vec::with_capacity(count);
156 for i in (0..(count * type_size)).step_by(4) {
157 vector.push(CBytes::new(bytes[i..i + type_size].to_vec()));
158 }
159
160 Ok(vector)
161}
162
163#[inline]
165pub fn decode_set(bytes: &[u8], version: Version) -> Result<Vec<CBytes>, io::Error> {
166 decode_list(bytes, version)
167}
168
169pub fn decode_map(bytes: &[u8], version: Version) -> Result<Vec<(CBytes, CBytes)>, io::Error> {
171 let mut cursor = io::Cursor::new(bytes);
172 let l = CInt::from_cursor(&mut cursor, version)
173 .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
174 let mut map = Vec::with_capacity(l as usize);
175 for _ in 0..l {
176 let k = CBytes::from_cursor(&mut cursor, version)
177 .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
178 let v = CBytes::from_cursor(&mut cursor, version)
179 .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
180 map.push((k, v));
181 }
182 Ok(map)
183}
184
185#[inline]
187pub fn decode_smallint(bytes: &[u8]) -> Result<i16, io::Error> {
188 try_i16_from_bytes(bytes)
189}
190
191#[inline]
193pub fn decode_tinyint(bytes: &[u8]) -> Result<i8, io::Error> {
194 Ok(bytes[0] as i8)
195}
196
197#[inline]
199pub fn decode_text(bytes: &[u8]) -> Result<String, FromUtf8Error> {
200 Ok(String::from_utf8_lossy(bytes).into_owned())
201}
202
203#[inline]
205pub fn decode_time(bytes: &[u8]) -> Result<i64, io::Error> {
206 try_i64_from_bytes(bytes)
207}
208
209#[inline]
211pub fn decode_timeuuid(bytes: &[u8]) -> Result<uuid::Uuid, uuid::Error> {
212 uuid::Uuid::from_slice(bytes)
213}
214
215#[inline]
217pub fn decode_varint(bytes: &[u8]) -> Result<BigInt, io::Error> {
218 Ok(BigInt::from_signed_bytes_be(bytes))
219}
220
221#[inline]
223pub fn decode_duration(bytes: &[u8]) -> Result<Duration, io::Error> {
224 let (months, month_bytes_read) =
225 i32::decode_var(bytes).ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?;
226
227 let (days, day_bytes_read) = i32::decode_var(&bytes[month_bytes_read..])
228 .ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?;
229
230 let (nanoseconds, _) = i64::decode_var(&bytes[(month_bytes_read + day_bytes_read)..])
231 .ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?;
232
233 Duration::new(months, days, nanoseconds)
234 .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))
235}
236
237pub fn decode_udt(bytes: &[u8], l: usize, version: Version) -> Result<Vec<CBytes>, io::Error> {
239 let mut cursor = io::Cursor::new(bytes);
240 let mut udt = Vec::with_capacity(l);
241 for _ in 0..l {
242 let v = CBytes::from_cursor(&mut cursor, version)
243 .or_else(|err| match err {
244 error::Error::Io(io_err) => {
245 if io_err.kind() == io::ErrorKind::UnexpectedEof {
246 Ok(CBytes::new_null())
247 } else {
248 Err(io_err.into())
249 }
250 }
251 _ => Err(err),
252 })
253 .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
254 udt.push(v);
255 }
256 Ok(udt)
257}
258
259pub fn decode_tuple(bytes: &[u8], l: usize, version: Version) -> Result<Vec<CBytes>, io::Error> {
262 let mut cursor = io::Cursor::new(bytes);
263 let mut tuple = Vec::with_capacity(l);
264 for _ in 0..l {
265 let v = CBytes::from_cursor(&mut cursor, version)
266 .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
267 tuple.push(v);
268 }
269 Ok(tuple)
270}
271
272#[cfg(test)]
274mod tests {
275 use super::super::super::frame::message_result::*;
276 use super::*;
277 use crate::types::{to_float, to_float_big};
278 use float_eq::*;
279 use std::net::IpAddr;
280
281 #[test]
282 fn decode_custom_test() {
283 assert_eq!(decode_custom(b"abcd").unwrap(), "abcd".to_string());
284 }
285
286 #[test]
287 fn decode_ascii_test() {
288 assert_eq!(decode_ascii(b"abcd").unwrap(), "abcd".to_string());
289 }
290
291 #[test]
292 fn decode_varchar_test() {
293 assert_eq!(decode_varchar(b"abcd").unwrap(), "abcd".to_string());
294 }
295
296 #[test]
297 fn decode_bigint_test() {
298 assert_eq!(decode_bigint(&[0, 0, 0, 0, 0, 0, 0, 3]).unwrap(), 3);
299 }
300
301 #[test]
302 fn decode_blob_test() {
303 assert_eq!(
304 decode_blob(&[0, 0, 0, 3]).unwrap().into_vec(),
305 vec![0, 0, 0, 3]
306 );
307 }
308
309 #[test]
310 fn decode_boolean_test() {
311 assert!(!decode_boolean(&[0]).unwrap());
312 assert!(decode_boolean(&[1]).unwrap());
313 assert!(decode_boolean(&[]).is_err());
314 }
315
316 #[test]
317 fn decode_int_test() {
318 assert_eq!(decode_int(&[0, 0, 0, 3]).unwrap(), 3);
319 }
320
321 #[test]
322 fn decode_date_test() {
323 assert_eq!(decode_date(&[0, 0, 0, 3]).unwrap(), 3);
324 }
325
326 #[test]
327 fn decode_double_test() {
328 let bytes = to_float_big(0.3);
329 assert_float_eq!(
330 decode_double(bytes.as_slice()).unwrap(),
331 0.3,
332 abs <= f64::EPSILON
333 );
334 }
335
336 #[test]
337 fn decode_float_test() {
338 let bytes = to_float(0.3);
339 assert_float_eq!(
340 decode_float(bytes.as_slice()).unwrap(),
341 0.3,
342 abs <= f32::EPSILON
343 );
344 }
345
346 #[test]
347 fn decode_inet_test() {
348 let bytes_v4 = &[0, 0, 0, 0];
349 match decode_inet(bytes_v4) {
350 Ok(IpAddr::V4(ref ip)) => assert_eq!(ip.octets(), [0, 0, 0, 0]),
351 _ => panic!("wrong ip v4 address"),
352 }
353
354 let bytes_v6 = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
355 match decode_inet(bytes_v6) {
356 Ok(IpAddr::V6(ref ip)) => assert_eq!(ip.segments(), [0, 0, 0, 0, 0, 0, 0, 0]),
357 _ => panic!("wrong ip v6 address"),
358 };
359 }
360
361 #[test]
362 fn decode_timestamp_test() {
363 assert_eq!(decode_timestamp(&[0, 0, 0, 0, 0, 0, 0, 3]).unwrap(), 3);
364 }
365
366 #[test]
367 fn decode_list_test() {
368 let results = decode_list(&[0, 0, 0, 1, 0, 0, 0, 2, 1, 2], Version::V4).unwrap();
369 assert_eq!(results.len(), 1);
370 assert_eq!(results[0].as_slice().unwrap(), &[1, 2]);
371 }
372
373 #[test]
374 fn decode_duration_test() {
375 let result = decode_duration(&[200, 1, 144, 3, 216, 4]).unwrap();
376 assert_eq!(result, Duration::new(100, 200, 300).unwrap());
377 }
378
379 #[test]
380 fn decode_set_test() {
381 let results = decode_set(&[0, 0, 0, 1, 0, 0, 0, 2, 1, 2], Version::V4).unwrap();
382 assert_eq!(results.len(), 1);
383 assert_eq!(results[0].as_slice().unwrap(), &[1, 2]);
384 }
385
386 #[test]
387 fn decode_map_test() {
388 let results = decode_map(
389 &[0, 0, 0, 1, 0, 0, 0, 2, 1, 2, 0, 0, 0, 2, 2, 1],
390 Version::V4,
391 )
392 .unwrap();
393 assert_eq!(results.len(), 1);
394 assert_eq!(results[0].0.as_slice().unwrap(), &[1, 2]);
395 assert_eq!(results[0].1.as_slice().unwrap(), &[2, 1]);
396 }
397
398 #[test]
399 fn decode_smallint_test() {
400 assert_eq!(decode_smallint(&[0, 10]).unwrap(), 10);
401 }
402
403 #[test]
404 fn decode_tinyint_test() {
405 assert_eq!(decode_tinyint(&[10]).unwrap(), 10);
406 }
407
408 #[test]
409 fn decode_decimal_test() {
410 assert_eq!(
411 decode_decimal(&[0, 0, 0, 0, 10u8]).unwrap(),
412 Decimal::new(10.into(), 0)
413 );
414
415 assert_eq!(
416 decode_decimal(&[0, 0, 0, 0, 0x00, 0x81]).unwrap(),
417 Decimal::new(129.into(), 0)
418 );
419
420 assert_eq!(
421 decode_decimal(&[0, 0, 0, 0, 0xFF, 0x7F]).unwrap(),
422 Decimal::new(BigInt::from(-129), 0)
423 );
424
425 assert_eq!(
426 decode_decimal(&[0, 0, 0, 1, 0x00, 0x81]).unwrap(),
427 Decimal::new(129.into(), 1)
428 );
429
430 assert_eq!(
431 decode_decimal(&[0, 0, 0, 1, 0xFF, 0x7F]).unwrap(),
432 Decimal::new(BigInt::from(-129), 1)
433 );
434 }
435
436 #[test]
437 fn decode_text_test() {
438 assert_eq!(decode_text(b"abcba").unwrap(), "abcba");
439 }
440
441 #[test]
442 fn decode_time_test() {
443 assert_eq!(decode_time(&[0, 0, 0, 0, 0, 0, 0, 10]).unwrap(), 10);
444 }
445
446 #[test]
447 fn decode_timeuuid_test() {
448 assert_eq!(
449 decode_timeuuid(&[4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87])
450 .unwrap()
451 .as_bytes(),
452 &[4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]
453 );
454 }
455
456 #[test]
457 fn decode_varint_test() {
458 assert_eq!(decode_varint(&[0x00]).unwrap(), 0.into());
459 assert_eq!(decode_varint(&[0x01]).unwrap(), 1.into());
460 assert_eq!(decode_varint(&[0x7F]).unwrap(), 127.into());
461 assert_eq!(decode_varint(&[0x00, 0x80]).unwrap(), 128.into());
462 assert_eq!(decode_varint(&[0x00, 0x81]).unwrap(), 129.into());
463 assert_eq!(decode_varint(&[0xFF]).unwrap(), BigInt::from(-1));
464 assert_eq!(decode_varint(&[0x80]).unwrap(), BigInt::from(-128));
465 assert_eq!(decode_varint(&[0xFF, 0x7F]).unwrap(), BigInt::from(-129));
466 }
467
468 #[test]
469 fn decode_udt_test() {
470 let udt = decode_udt(&[0, 0, 0, 2, 1, 2], 1, Version::V4).unwrap();
471 assert_eq!(udt.len(), 1);
472 assert_eq!(udt[0].as_slice().unwrap(), &[1, 2]);
473 }
474
475 #[test]
476 fn as_rust_blob_test() {
477 let d_type = ColTypeOption {
478 id: ColType::Blob,
479 value: None,
480 };
481 let data = CBytes::new(vec![1, 2, 3]);
482 assert_eq!(
483 as_rust_type!(d_type, data, Blob)
484 .unwrap()
485 .unwrap()
486 .into_vec(),
487 vec![1, 2, 3]
488 );
489 let wrong_type = ColTypeOption {
490 id: ColType::Map,
491 value: None,
492 };
493 assert!(as_rust_type!(wrong_type, data, Blob).is_err());
494 }
495
496 #[test]
497 fn as_rust_v4_blob_test() {
498 let d_type = ColTypeOption {
499 id: ColType::Custom,
500 value: Some(ColTypeOptionValue::CString(
501 "org.apache.cassandra.db.marshal.BytesType".into(),
502 )),
503 };
504 let data = CBytes::new(vec![1, 2, 3]);
505 assert_eq!(
506 as_rust_type!(d_type, data, Blob)
507 .unwrap()
508 .unwrap()
509 .into_vec(),
510 vec![1, 2, 3]
511 );
512 }
513
514 #[test]
515 fn as_rust_string_test() {
516 let type_custom = ColTypeOption {
517 id: ColType::Custom,
518 value: None,
519 };
520 let type_ascii = ColTypeOption {
521 id: ColType::Ascii,
522 value: None,
523 };
524 let type_varchar = ColTypeOption {
525 id: ColType::Varchar,
526 value: None,
527 };
528 let data = CBytes::new(b"abc".to_vec());
529 assert_eq!(
530 as_rust_type!(type_custom, data, String).unwrap().unwrap(),
531 "abc"
532 );
533 assert_eq!(
534 as_rust_type!(type_ascii, data, String).unwrap().unwrap(),
535 "abc"
536 );
537 assert_eq!(
538 as_rust_type!(type_varchar, data, String).unwrap().unwrap(),
539 "abc"
540 );
541 let wrong_type = ColTypeOption {
542 id: ColType::Map,
543 value: None,
544 };
545 assert!(as_rust_type!(wrong_type, data, String).is_err());
546 }
547
548 #[test]
549 fn as_rust_bool_test() {
550 let type_boolean = ColTypeOption {
551 id: ColType::Boolean,
552 value: None,
553 };
554 let data_true = CBytes::new(vec![1]);
555 let data_false = CBytes::new(vec![0]);
556 assert!(as_rust_type!(type_boolean, data_true, bool)
557 .unwrap()
558 .unwrap());
559 assert!(!as_rust_type!(type_boolean, data_false, bool)
560 .unwrap()
561 .unwrap());
562 let wrong_type = ColTypeOption {
563 id: ColType::Map,
564 value: None,
565 };
566 assert!(as_rust_type!(wrong_type, data_false, bool).is_err());
567 }
568
569 #[test]
570 fn as_rust_v4_bool_test() {
571 let type_boolean = ColTypeOption {
572 id: ColType::Custom,
573 value: Some(ColTypeOptionValue::CString(
574 "org.apache.cassandra.db.marshal.BooleanType".into(),
575 )),
576 };
577 let data_true = CBytes::new(vec![1]);
578 let data_false = CBytes::new(vec![0]);
579 assert!(as_rust_type!(type_boolean, data_true, bool)
580 .unwrap()
581 .unwrap());
582 assert!(!as_rust_type!(type_boolean, data_false, bool)
583 .unwrap()
584 .unwrap());
585 }
586
587 #[test]
588 fn as_rust_i64_test() {
589 let type_bigint = ColTypeOption {
590 id: ColType::Bigint,
591 value: None,
592 };
593 let type_timestamp = ColTypeOption {
594 id: ColType::Timestamp,
595 value: None,
596 };
597 let type_time = ColTypeOption {
598 id: ColType::Time,
599 value: None,
600 };
601 let data = CBytes::new(vec![0, 0, 0, 0, 0, 0, 0, 100]);
602 assert_eq!(as_rust_type!(type_bigint, data, i64).unwrap().unwrap(), 100);
603 assert_eq!(
604 as_rust_type!(type_timestamp, data, i64).unwrap().unwrap(),
605 100
606 );
607 assert_eq!(as_rust_type!(type_time, data, i64).unwrap().unwrap(), 100);
608 let wrong_type = ColTypeOption {
609 id: ColType::Map,
610 value: None,
611 };
612 assert!(as_rust_type!(wrong_type, data, i64).is_err());
613 }
614
615 #[test]
616 fn as_rust_v4_i64_test() {
617 let type_bigint = ColTypeOption {
618 id: ColType::Custom,
619 value: Some(ColTypeOptionValue::CString(
620 "org.apache.cassandra.db.marshal.LongType".into(),
621 )),
622 };
623 let type_timestamp = ColTypeOption {
624 id: ColType::Custom,
625 value: Some(ColTypeOptionValue::CString(
626 "org.apache.cassandra.db.marshal.TimestampType".into(),
627 )),
628 };
629 let type_time = ColTypeOption {
630 id: ColType::Custom,
631 value: Some(ColTypeOptionValue::CString(
632 "org.apache.cassandra.db.marshal.TimeType".into(),
633 )),
634 };
635 let data = CBytes::new(vec![0, 0, 0, 0, 0, 0, 0, 100]);
636 assert_eq!(as_rust_type!(type_bigint, data, i64).unwrap().unwrap(), 100);
637 assert_eq!(
638 as_rust_type!(type_timestamp, data, i64).unwrap().unwrap(),
639 100
640 );
641 assert_eq!(as_rust_type!(type_time, data, i64).unwrap().unwrap(), 100);
642 }
643
644 #[test]
645 fn as_rust_i32_test() {
646 let type_int = ColTypeOption {
647 id: ColType::Int,
648 value: None,
649 };
650 let type_date = ColTypeOption {
651 id: ColType::Date,
652 value: None,
653 };
654 let data = CBytes::new(vec![0, 0, 0, 100]);
655 assert_eq!(as_rust_type!(type_int, data, i32).unwrap().unwrap(), 100);
656 assert_eq!(as_rust_type!(type_date, data, i32).unwrap().unwrap(), 100);
657 let wrong_type = ColTypeOption {
658 id: ColType::Map,
659 value: None,
660 };
661 assert!(as_rust_type!(wrong_type, data, i32).is_err());
662 }
663
664 #[test]
665 fn as_rust_v4_i32_test() {
666 let type_int = ColTypeOption {
667 id: ColType::Custom,
668 value: Some(ColTypeOptionValue::CString(
669 "org.apache.cassandra.db.marshal.Int32Type".into(),
670 )),
671 };
672 let type_date = ColTypeOption {
673 id: ColType::Custom,
674 value: Some(ColTypeOptionValue::CString(
675 "org.apache.cassandra.db.marshal.SimpleDateType".into(),
676 )),
677 };
678 let data = CBytes::new(vec![0, 0, 0, 100]);
679 assert_eq!(as_rust_type!(type_int, data, i32).unwrap().unwrap(), 100);
680 assert_eq!(as_rust_type!(type_date, data, i32).unwrap().unwrap(), 100);
681 }
682
683 #[test]
684 fn as_rust_i16_test() {
685 let type_smallint = ColTypeOption {
686 id: ColType::Smallint,
687 value: None,
688 };
689 let data = CBytes::new(vec![0, 100]);
690 assert_eq!(
691 as_rust_type!(type_smallint, data, i16).unwrap().unwrap(),
692 100
693 );
694 let wrong_type = ColTypeOption {
695 id: ColType::Map,
696 value: None,
697 };
698 assert!(as_rust_type!(wrong_type, data, i16).is_err());
699 }
700
701 #[test]
702 fn as_rust_v4_i16_test() {
703 let type_smallint = ColTypeOption {
704 id: ColType::Custom,
705 value: Some(ColTypeOptionValue::CString(
706 "org.apache.cassandra.db.marshal.ShortType".into(),
707 )),
708 };
709 let data = CBytes::new(vec![0, 100]);
710 assert_eq!(
711 as_rust_type!(type_smallint, data, i16).unwrap().unwrap(),
712 100
713 );
714 }
715
716 #[test]
717 fn as_rust_i8_test() {
718 let type_tinyint = ColTypeOption {
719 id: ColType::Tinyint,
720 value: None,
721 };
722 let data = CBytes::new(vec![100]);
723 assert_eq!(as_rust_type!(type_tinyint, data, i8).unwrap().unwrap(), 100);
724 let wrong_type = ColTypeOption {
725 id: ColType::Map,
726 value: None,
727 };
728 assert!(as_rust_type!(wrong_type, data, i8).is_err());
729 }
730
731 #[test]
732 fn as_rust_v4_i8_test() {
733 let type_tinyint = ColTypeOption {
734 id: ColType::Custom,
735 value: Some(ColTypeOptionValue::CString(
736 "org.apache.cassandra.db.marshal.ByteType".into(),
737 )),
738 };
739 let data = CBytes::new(vec![100]);
740 assert_eq!(as_rust_type!(type_tinyint, data, i8).unwrap().unwrap(), 100);
741 }
742
743 #[test]
744 fn as_rust_f64_test() {
745 let type_double = ColTypeOption {
746 id: ColType::Double,
747 value: None,
748 };
749 let data = CBytes::new(to_float_big(0.1_f64));
750 assert_float_eq!(
751 as_rust_type!(type_double, data, f64).unwrap().unwrap(),
752 0.1,
753 abs <= f64::EPSILON
754 );
755 let wrong_type = ColTypeOption {
756 id: ColType::Map,
757 value: None,
758 };
759 assert!(as_rust_type!(wrong_type, data, f64).is_err());
760 }
761
762 #[test]
763 fn as_rust_v4_f64_test() {
764 let type_double = ColTypeOption {
765 id: ColType::Custom,
766 value: Some(ColTypeOptionValue::CString(
767 "org.apache.cassandra.db.marshal.DoubleType".into(),
768 )),
769 };
770 let data = CBytes::new(to_float_big(0.1_f64));
771 assert_float_eq!(
772 as_rust_type!(type_double, data, f64).unwrap().unwrap(),
773 0.1,
774 abs <= f64::EPSILON
775 );
776 }
777
778 #[test]
779 fn as_rust_f32_test() {
780 let type_float = ColTypeOption {
782 id: ColType::Float,
783 value: None,
784 };
785 let data = CBytes::new(to_float(0.1_f32));
786 assert_float_eq!(
788 as_rust_type!(type_float, data, f32).unwrap().unwrap(),
789 0.1,
790 abs <= f32::EPSILON
791 );
792 let wrong_type = ColTypeOption {
793 id: ColType::Map,
794 value: None,
795 };
796 assert!(as_rust_type!(wrong_type, data, f32).is_err());
797 }
798
799 #[test]
800 fn as_rust_v4_f32_test() {
801 let type_float = ColTypeOption {
803 id: ColType::Custom,
804 value: Some(ColTypeOptionValue::CString(
805 "org.apache.cassandra.db.marshal.FloatType".into(),
806 )),
807 };
808 let data = CBytes::new(to_float(0.1_f32));
809 assert_float_eq!(
811 as_rust_type!(type_float, data, f32).unwrap().unwrap(),
812 0.1,
813 abs <= f32::EPSILON
814 );
815 }
816
817 #[test]
818 fn as_rust_inet_test() {
819 let type_inet = ColTypeOption {
820 id: ColType::Inet,
821 value: None,
822 };
823 let data = CBytes::new(vec![0, 0, 0, 0]);
824
825 match as_rust_type!(type_inet, data, IpAddr) {
826 Ok(Some(IpAddr::V4(ref ip))) => assert_eq!(ip.octets(), [0, 0, 0, 0]),
827 _ => panic!("wrong ip v4 address"),
828 }
829 let wrong_type = ColTypeOption {
830 id: ColType::Map,
831 value: None,
832 };
833 assert!(as_rust_type!(wrong_type, data, f32).is_err());
834 }
835
836 #[test]
837 fn as_rust_v4_inet_test() {
838 let type_inet = ColTypeOption {
839 id: ColType::Custom,
840 value: Some(ColTypeOptionValue::CString(
841 "org.apache.cassandra.db.marshal.InetAddressType".into(),
842 )),
843 };
844 let data = CBytes::new(vec![0, 0, 0, 0]);
845
846 match as_rust_type!(type_inet, data, IpAddr) {
847 Ok(Some(IpAddr::V4(ref ip))) => assert_eq!(ip.octets(), [0, 0, 0, 0]),
848 _ => panic!("wrong ip v4 address"),
849 }
850 }
851}