1use self::cassandra_type::CassandraType;
2use crate::error::{column_is_empty_err, Error as CdrsError, Result as CDRSResult};
3use crate::frame::traits::FromCursor;
4use crate::frame::{Serialize, Version};
5use crate::types::data_serialization_types::*;
6use derive_more::Constructor;
7use std::convert::TryInto;
8use std::io::{self, Write};
9use std::io::{Cursor, Read};
10use std::net::{IpAddr, SocketAddr};
11
12pub const SHORT_LEN: usize = 2;
13pub const INT_LEN: usize = 4;
14pub const LONG_LEN: usize = 8;
15pub const UUID_LEN: usize = 16;
16
17const NULL_INT_LEN: CInt = -1;
18const NULL_SHORT_LEN: CIntShort = -1;
19
20#[macro_use]
21pub mod blob;
22pub mod cassandra_type;
23pub mod data_serialization_types;
24pub mod decimal;
25pub mod duration;
26pub mod from_cdrs;
27pub mod list;
28pub mod map;
29pub mod rows;
30pub mod tuple;
31pub mod udt;
32pub mod value;
33pub mod vector;
34
35pub mod prelude {
36 pub use crate::error::{Error, Result};
37 pub use crate::frame::{TryFromRow, TryFromUdt};
38 pub use crate::types::blob::Blob;
39 pub use crate::types::decimal::Decimal;
40 pub use crate::types::duration::Duration;
41 pub use crate::types::list::List;
42 pub use crate::types::map::Map;
43 pub use crate::types::rows::Row;
44 pub use crate::types::tuple::Tuple;
45 pub use crate::types::udt::Udt;
46 pub use crate::types::value::{Bytes, Value};
47 pub use crate::types::AsRustType;
48}
49
50pub trait AsCassandraType {
51 fn as_cassandra_type(&self) -> CDRSResult<Option<CassandraType>>;
52}
53
54pub trait AsRustType<T> {
56 fn as_rust_type(&self) -> CDRSResult<Option<T>>;
57
58 fn as_r_type(&self) -> CDRSResult<T> {
59 self.as_rust_type()
60 .and_then(|op| op.ok_or_else(|| CdrsError::from("Value is null or non-set")))
61 }
62}
63
64pub trait AsRust {
65 fn as_rust<R>(&self) -> CDRSResult<Option<R>>
66 where
67 Self: AsRustType<R>,
68 {
69 self.as_rust_type()
70 }
71
72 fn as_r_rust<T>(&self) -> CDRSResult<T>
73 where
74 Self: AsRustType<T>,
75 {
76 self.as_rust()
77 .and_then(|op| op.ok_or_else(|| "Value is null or non-set".into()))
78 }
79}
80
81pub trait IntoRustByName<R> {
83 fn get_by_name(&self, name: &str) -> CDRSResult<Option<R>>;
84
85 fn get_r_by_name(&self, name: &str) -> CDRSResult<R> {
86 self.get_by_name(name)
87 .and_then(|op| op.ok_or_else(|| column_is_empty_err(name)))
88 }
89}
90
91pub trait ByName {
92 fn by_name<R>(&self, name: &str) -> CDRSResult<Option<R>>
93 where
94 Self: IntoRustByName<R>,
95 {
96 self.get_by_name(name)
97 }
98
99 fn r_by_name<R>(&self, name: &str) -> CDRSResult<R>
100 where
101 Self: IntoRustByName<R>,
102 {
103 self.by_name(name)
104 .and_then(|op| op.ok_or_else(|| column_is_empty_err(name)))
105 }
106}
107
108pub trait IntoRustByIndex<R> {
110 fn get_by_index(&self, index: usize) -> CDRSResult<Option<R>>;
111
112 fn get_r_by_index(&self, index: usize) -> CDRSResult<R> {
113 self.get_by_index(index)
114 .and_then(|op| op.ok_or_else(|| column_is_empty_err(index)))
115 }
116}
117
118pub trait ByIndex {
119 fn by_index<R>(&self, index: usize) -> CDRSResult<Option<R>>
120 where
121 Self: IntoRustByIndex<R>,
122 {
123 self.get_by_index(index)
124 }
125
126 fn r_by_index<R>(&self, index: usize) -> CDRSResult<R>
127 where
128 Self: IntoRustByIndex<R>,
129 {
130 self.by_index(index)
131 .and_then(|op| op.ok_or_else(|| column_is_empty_err(index)))
132 }
133}
134
135#[inline]
136fn convert_to_array<const S: usize>(bytes: &[u8]) -> Result<[u8; S], io::Error> {
137 bytes
138 .try_into()
139 .map_err(|error| io::Error::new(io::ErrorKind::UnexpectedEof, error))
140}
141
142#[inline]
143pub fn try_u64_from_bytes(bytes: &[u8]) -> Result<u64, io::Error> {
144 convert_to_array(bytes).map(u64::from_be_bytes)
145}
146
147#[inline]
148pub fn try_i64_from_bytes(bytes: &[u8]) -> Result<i64, io::Error> {
149 convert_to_array(bytes).map(i64::from_be_bytes)
150}
151
152#[inline]
153pub fn try_i32_from_bytes(bytes: &[u8]) -> Result<i32, io::Error> {
154 convert_to_array(bytes).map(i32::from_be_bytes)
155}
156
157#[inline]
158pub fn try_i16_from_bytes(bytes: &[u8]) -> Result<i16, io::Error> {
159 convert_to_array(bytes).map(i16::from_be_bytes)
160}
161
162#[inline]
163pub fn try_f32_from_bytes(bytes: &[u8]) -> Result<f32, io::Error> {
164 convert_to_array(bytes).map(f32::from_be_bytes)
165}
166
167#[inline]
168pub fn try_f64_from_bytes(bytes: &[u8]) -> Result<f64, io::Error> {
169 convert_to_array(bytes).map(f64::from_be_bytes)
170}
171
172#[inline]
173pub fn u16_from_bytes(bytes: [u8; 2]) -> u16 {
174 u16::from_be_bytes(bytes)
175}
176
177#[inline]
178pub fn to_short(int: i16) -> Vec<u8> {
179 int.to_be_bytes().into()
180}
181
182#[inline]
183pub fn to_int(int: i32) -> Vec<u8> {
184 int.to_be_bytes().into()
185}
186
187#[inline]
188pub fn to_bigint(int: i64) -> Vec<u8> {
189 int.to_be_bytes().into()
190}
191
192#[inline]
193pub fn to_u_short(int: u16) -> Vec<u8> {
194 int.to_be_bytes().into()
195}
196
197#[inline]
198pub fn to_u_int(int: u32) -> Vec<u8> {
199 int.to_be_bytes().into()
200}
201
202#[inline]
203pub fn to_u_big(int: u64) -> Vec<u8> {
204 int.to_be_bytes().into()
205}
206
207#[inline]
208pub fn to_float(f: f32) -> Vec<u8> {
209 f.to_be_bytes().into()
210}
211
212#[inline]
213pub fn to_float_big(f: f64) -> Vec<u8> {
214 f.to_be_bytes().into()
215}
216
217pub fn serialize_str(cursor: &mut Cursor<&mut Vec<u8>>, value: &str, version: Version) {
218 let len = value.len() as CIntShort;
219 len.serialize(cursor, version);
220 let _ = cursor.write(value.as_bytes());
221}
222
223pub(crate) fn serialize_str_long(cursor: &mut Cursor<&mut Vec<u8>>, value: &str, version: Version) {
224 let len = value.len() as CInt;
225 len.serialize(cursor, version);
226 let _ = cursor.write(value.as_bytes());
227}
228
229pub(crate) fn from_cursor_str<'a>(cursor: &mut Cursor<&'a [u8]>) -> CDRSResult<&'a str> {
230 let mut buff = [0; SHORT_LEN];
231 cursor.read_exact(&mut buff)?;
232
233 let len = CIntShort::from_be_bytes(buff);
234 let body_bytes = cursor_next_value_ref(cursor, len as usize)?;
235
236 std::str::from_utf8(body_bytes).map_err(Into::into)
237}
238
239pub(crate) fn from_cursor_str_long<'a>(cursor: &mut Cursor<&'a [u8]>) -> CDRSResult<&'a str> {
240 let mut buff = [0; INT_LEN];
241 cursor.read_exact(&mut buff)?;
242
243 let len = CInt::from_be_bytes(buff);
244 let body_bytes = cursor_next_value_ref(cursor, len as usize)?;
245
246 std::str::from_utf8(body_bytes).map_err(Into::into)
247}
248
249pub(crate) fn serialize_str_list<'a>(
250 cursor: &mut Cursor<&mut Vec<u8>>,
251 list: impl ExactSizeIterator<Item = &'a str>,
252 version: Version,
253) {
254 let len = list.len() as CIntShort;
255 len.serialize(cursor, version);
256
257 for string in list {
258 serialize_str(cursor, string, version);
259 }
260}
261
262pub fn from_cursor_string_list(cursor: &mut Cursor<&[u8]>) -> CDRSResult<Vec<String>> {
263 let mut buff = [0; SHORT_LEN];
264 cursor.read_exact(&mut buff)?;
265
266 let len = i16::from_be_bytes(buff);
267 let mut list = Vec::with_capacity(len as usize);
268 for _ in 0..len {
269 list.push(from_cursor_str(cursor)?.to_string());
270 }
271
272 Ok(list)
273}
274
275#[derive(Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
276pub struct CBytes {
278 bytes: Option<Vec<u8>>,
279}
280
281impl CBytes {
282 #[inline]
283 pub fn new(bytes: Vec<u8>) -> CBytes {
284 CBytes { bytes: Some(bytes) }
285 }
286
287 #[inline]
289 pub fn new_null() -> CBytes {
290 CBytes { bytes: None }
291 }
292
293 #[inline]
295 pub fn into_bytes(self) -> Option<Vec<u8>> {
296 self.bytes
297 }
298
299 #[inline]
300 pub fn as_slice(&self) -> Option<&[u8]> {
301 self.bytes.as_deref()
302 }
303
304 #[inline]
305 pub fn is_null_or_empty(&self) -> bool {
306 match &self.bytes {
307 None => true,
308 Some(bytes) => bytes.is_empty(),
309 }
310 }
311}
312
313impl FromCursor for CBytes {
314 fn from_cursor(cursor: &mut Cursor<&[u8]>, version: Version) -> CDRSResult<CBytes> {
315 let len = CInt::from_cursor(cursor, version)?;
316 if len < 0 {
318 return Ok(CBytes { bytes: None });
319 }
320
321 cursor_next_value(cursor, len as usize).map(CBytes::new)
322 }
323}
324
325impl Serialize for CBytes {
326 fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
327 match &self.bytes {
328 Some(bytes) => {
329 let len = bytes.len() as CInt;
330 len.serialize(cursor, version);
331 bytes.serialize(cursor, version);
332 }
333 None => NULL_INT_LEN.serialize(cursor, version),
334 }
335 }
336}
337
338#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
340pub struct CBytesShort {
341 bytes: Option<Vec<u8>>,
342}
343
344impl CBytesShort {
345 #[inline]
346 pub fn new(bytes: Vec<u8>) -> CBytesShort {
347 CBytesShort { bytes: Some(bytes) }
348 }
349
350 #[inline]
352 pub fn into_bytes(self) -> Option<Vec<u8>> {
353 self.bytes
354 }
355
356 #[inline]
357 pub fn serialized_len(&self) -> usize {
358 SHORT_LEN
359 + if let Some(bytes) = &self.bytes {
360 bytes.len()
361 } else {
362 0
363 }
364 }
365}
366
367impl FromCursor for CBytesShort {
368 fn from_cursor(cursor: &mut Cursor<&[u8]>, version: Version) -> CDRSResult<CBytesShort> {
371 let len = CIntShort::from_cursor(cursor, version)?;
372
373 if len < 0 {
374 return Ok(CBytesShort { bytes: None });
375 }
376
377 cursor_next_value(cursor, len as usize).map(CBytesShort::new)
378 }
379}
380
381impl Serialize for CBytesShort {
382 fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
383 match &self.bytes {
384 Some(bytes) => {
385 let len = bytes.len() as CIntShort;
386 len.serialize(cursor, version);
387 bytes.serialize(cursor, version);
388 }
389 None => NULL_SHORT_LEN.serialize(cursor, version),
390 }
391 }
392}
393
394pub type CInt = i32;
396
397impl FromCursor for CInt {
398 fn from_cursor(cursor: &mut Cursor<&[u8]>, _version: Version) -> CDRSResult<CInt> {
399 let mut buff = [0; INT_LEN];
400 cursor.read_exact(&mut buff)?;
401
402 Ok(CInt::from_be_bytes(buff))
403 }
404}
405
406pub type CIntShort = i16;
408
409impl FromCursor for CIntShort {
410 fn from_cursor(cursor: &mut Cursor<&[u8]>, _version: Version) -> CDRSResult<CIntShort> {
411 let mut buff = [0; SHORT_LEN];
412 cursor.read_exact(&mut buff)?;
413
414 Ok(CIntShort::from_be_bytes(buff))
415 }
416}
417
418pub type CLong = i64;
420
421impl FromCursor for CLong {
422 fn from_cursor(cursor: &mut Cursor<&[u8]>, _version: Version) -> CDRSResult<Self> {
423 let mut buff = [0; LONG_LEN];
424 cursor.read_exact(&mut buff)?;
425
426 Ok(CLong::from_be_bytes(buff))
427 }
428}
429
430impl Serialize for SocketAddr {
431 fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
432 match self.ip() {
433 IpAddr::V4(v4) => {
434 [4].serialize(cursor, version);
435 v4.octets().serialize(cursor, version);
436 }
437 IpAddr::V6(v6) => {
438 [16].serialize(cursor, version);
439 v6.octets().serialize(cursor, version);
440 }
441 }
442
443 to_int(self.port().into()).serialize(cursor, version);
444 }
445}
446
447impl FromCursor for SocketAddr {
448 fn from_cursor(cursor: &mut Cursor<&[u8]>, version: Version) -> CDRSResult<Self> {
449 let mut buff = [0];
450 cursor.read_exact(&mut buff)?;
451
452 let n = buff[0];
453
454 let ip = decode_inet(cursor_next_value(cursor, n as usize)?.as_slice())?;
455 let port = CInt::from_cursor(cursor, version)?;
456 Ok(SocketAddr::new(ip, port as u16))
457 }
458}
459
460pub fn cursor_next_value(cursor: &mut Cursor<&[u8]>, len: usize) -> CDRSResult<Vec<u8>> {
461 let mut buff = vec![0u8; len];
462 cursor.read_exact(&mut buff)?;
463 Ok(buff)
464}
465
466pub fn cursor_next_value_ref<'a>(
467 cursor: &mut Cursor<&'a [u8]>,
468 len: usize,
469) -> CDRSResult<&'a [u8]> {
470 let start = cursor.position() as usize;
471 let result = &cursor.get_ref()[start..start + len];
472 cursor.set_position(cursor.position() + len as u64);
473
474 if result.len() != len {
475 Err(CdrsError::General(
476 "cursor_next_value_ref could not retrieve a full slice".into(),
477 ))
478 } else {
479 Ok(result)
480 }
481}
482
483#[cfg(test)]
484mod tests {
485 use super::*;
486 use crate::frame::traits::FromCursor;
487 use num_bigint::BigInt;
488 use std::io::Cursor;
489
490 fn from_i_bytes(bytes: &[u8]) -> i64 {
491 try_i64_from_bytes(bytes).unwrap()
492 }
493
494 fn try_u16_from_bytes(bytes: &[u8]) -> Result<u16, io::Error> {
495 Ok(u16::from_be_bytes(convert_to_array(bytes)?))
496 }
497
498 fn to_varint(int: BigInt) -> Vec<u8> {
499 int.to_signed_bytes_be()
500 }
501
502 #[test]
503 fn test_from_cursor_str() {
504 let a = &[0, 3, 102, 111, 111, 0];
505 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
506 let cstring = from_cursor_str(&mut cursor).unwrap();
507 assert_eq!(cstring, "foo");
508 }
509
510 #[test]
511 fn test_from_cursor_str_long() {
512 let a = &[0, 0, 0, 3, 102, 111, 111, 0];
513 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
514 let cstring = from_cursor_str_long(&mut cursor).unwrap();
515 assert_eq!(cstring, "foo");
516 }
517
518 #[test]
519 fn test_serialize_str() {
520 let input = "foo";
521
522 let mut buf = vec![];
523 serialize_str(&mut Cursor::new(&mut buf), input, Version::V4);
524
525 assert_eq!(buf, &[0, 3, 102, 111, 111]);
526 }
527
528 #[test]
529 fn test_serialize_str_long() {
530 let input = "foo";
531
532 let mut buf = vec![];
533 serialize_str_long(&mut Cursor::new(&mut buf), input, Version::V4);
534
535 assert_eq!(buf, &[0, 0, 0, 3, 102, 111, 111]);
536 }
537
538 #[test]
539 fn test_cstringlist() {
540 let a = &[0, 2, 0, 3, 102, 111, 111, 0, 3, 102, 111, 112];
541 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
542 let list = from_cursor_string_list(&mut cursor).unwrap();
543
544 assert_eq!(list, vec!("foo".to_string(), "fop".to_string()));
545 }
546
547 #[test]
549 fn test_cbytes_new() {
550 let bytes_vec = vec![1, 2, 3];
551 let _ = CBytes::new(bytes_vec);
552 }
553
554 #[test]
555 fn test_cbytes_into_bytes() {
556 let cbytes = CBytes::new(vec![1, 2, 3]);
557 assert_eq!(cbytes.into_bytes().unwrap(), &[1, 2, 3]);
558 }
559
560 #[test]
561 fn test_cbytes_from_cursor() {
562 let a = &[0, 0, 0, 3, 1, 2, 3];
563 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
564 let cbytes = CBytes::from_cursor(&mut cursor, Version::V4).unwrap();
565 assert_eq!(cbytes.into_bytes().unwrap(), vec![1, 2, 3]);
566 }
567
568 #[test]
569 fn test_cbytes_serialize() {
570 let bytes_vec = vec![1, 2, 3];
571 let cbytes = CBytes::new(bytes_vec);
572 assert_eq!(
573 cbytes.serialize_to_vec(Version::V4),
574 vec![0, 0, 0, 3, 1, 2, 3]
575 );
576 }
577
578 #[test]
580 fn test_cbytesshort_new() {
581 let bytes_vec = vec![1, 2, 3];
582 let _ = CBytesShort::new(bytes_vec);
583 }
584
585 #[test]
586 fn test_cbytesshort_into_bytes() {
587 let cbytes = CBytesShort::new(vec![1, 2, 3]);
588 assert_eq!(cbytes.into_bytes().unwrap(), vec![1, 2, 3]);
589 }
590
591 #[test]
592 fn test_cbytesshort_from_cursor() {
593 let a = &[0, 3, 1, 2, 3];
594 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
595 let cbytes = CBytesShort::from_cursor(&mut cursor, Version::V4).unwrap();
596 assert_eq!(cbytes.into_bytes().unwrap(), vec![1, 2, 3]);
597 }
598
599 #[test]
600 fn test_cbytesshort_serialize() {
601 let bytes_vec: Vec<u8> = vec![1, 2, 3];
602 let cbytes = CBytesShort::new(bytes_vec);
603 assert_eq!(cbytes.serialize_to_vec(Version::V4), vec![0, 3, 1, 2, 3]);
604 }
605
606 #[test]
607 fn test_cint_from_cursor() {
608 let a = &[0, 0, 0, 5];
609 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
610 let i = CInt::from_cursor(&mut cursor, Version::V4).unwrap();
611 assert_eq!(i, 5);
612 }
613
614 #[test]
615 fn test_cintshort_from_cursor() {
616 let a = &[0, 5];
617 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
618 let i = CIntShort::from_cursor(&mut cursor, Version::V4).unwrap();
619 assert_eq!(i, 5);
620 }
621
622 #[test]
623 fn test_cursor_next_value() {
624 let a = &[0, 1, 2, 3, 4];
625 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
626 let l = 3;
627 let val = cursor_next_value(&mut cursor, l).unwrap();
628 assert_eq!(val, vec![0, 1, 2]);
629 }
630
631 #[test]
632 fn test_try_u16_from_bytes() {
633 let bytes: [u8; 2] = [0, 12]; let val = try_u16_from_bytes(&bytes);
635 assert_eq!(val.unwrap(), 12u16);
636 }
637
638 #[test]
639 fn test_from_i_bytes() {
640 let bytes: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 12]; let val = from_i_bytes(&bytes);
642 assert_eq!(val, 12i64);
643 }
644
645 #[test]
646 fn test_to_varint() {
647 assert_eq!(to_varint(0.into()), vec![0x00]);
648 assert_eq!(to_varint(1.into()), vec![0x01]);
649 assert_eq!(to_varint(127.into()), vec![0x7F]);
650 assert_eq!(to_varint(128.into()), vec![0x00, 0x80]);
651 assert_eq!(to_varint(129.into()), vec![0x00, 0x81]);
652 assert_eq!(to_varint(BigInt::from(-1)), vec![0xFF]);
653 assert_eq!(to_varint(BigInt::from(-128)), vec![0x80]);
654 assert_eq!(to_varint(BigInt::from(-129)), vec![0xFF, 0x7F]);
655 }
656}