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 #[inline]
313 #[deprecated(note = "Use into_bytes().")]
314 pub fn into_plain(self) -> Option<Vec<u8>> {
315 self.bytes
316 }
317}
318
319impl FromCursor for CBytes {
320 fn from_cursor(cursor: &mut Cursor<&[u8]>, version: Version) -> CDRSResult<CBytes> {
321 let len = CInt::from_cursor(cursor, version)?;
322 if len < 0 {
324 return Ok(CBytes { bytes: None });
325 }
326
327 cursor_next_value(cursor, len as usize).map(CBytes::new)
328 }
329}
330
331impl Serialize for CBytes {
332 fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
333 match &self.bytes {
334 Some(bytes) => {
335 let len = bytes.len() as CInt;
336 len.serialize(cursor, version);
337 bytes.serialize(cursor, version);
338 }
339 None => NULL_INT_LEN.serialize(cursor, version),
340 }
341 }
342}
343
344#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
346pub struct CBytesShort {
347 bytes: Option<Vec<u8>>,
348}
349
350impl CBytesShort {
351 #[inline]
352 pub fn new(bytes: Vec<u8>) -> CBytesShort {
353 CBytesShort { bytes: Some(bytes) }
354 }
355
356 #[inline]
358 pub fn into_bytes(self) -> Option<Vec<u8>> {
359 self.bytes
360 }
361
362 #[inline]
363 pub fn serialized_len(&self) -> usize {
364 SHORT_LEN
365 + if let Some(bytes) = &self.bytes {
366 bytes.len()
367 } else {
368 0
369 }
370 }
371
372 #[inline]
373 #[deprecated(note = "Use into_bytes().")]
374 pub fn into_plain(self) -> Option<Vec<u8>> {
375 self.bytes
376 }
377}
378
379impl FromCursor for CBytesShort {
380 fn from_cursor(cursor: &mut Cursor<&[u8]>, version: Version) -> CDRSResult<CBytesShort> {
383 let len = CIntShort::from_cursor(cursor, version)?;
384
385 if len < 0 {
386 return Ok(CBytesShort { bytes: None });
387 }
388
389 cursor_next_value(cursor, len as usize)
390 .map(CBytesShort::new)
391 .map_err(Into::into)
392 }
393}
394
395impl Serialize for CBytesShort {
396 fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
397 match &self.bytes {
398 Some(bytes) => {
399 let len = bytes.len() as CIntShort;
400 len.serialize(cursor, version);
401 bytes.serialize(cursor, version);
402 }
403 None => NULL_SHORT_LEN.serialize(cursor, version),
404 }
405 }
406}
407
408pub type CInt = i32;
410
411impl FromCursor for CInt {
412 fn from_cursor(cursor: &mut Cursor<&[u8]>, _version: Version) -> CDRSResult<CInt> {
413 let mut buff = [0; INT_LEN];
414 cursor.read_exact(&mut buff)?;
415
416 Ok(CInt::from_be_bytes(buff))
417 }
418}
419
420pub type CIntShort = i16;
422
423impl FromCursor for CIntShort {
424 fn from_cursor(cursor: &mut Cursor<&[u8]>, _version: Version) -> CDRSResult<CIntShort> {
425 let mut buff = [0; SHORT_LEN];
426 cursor.read_exact(&mut buff)?;
427
428 Ok(CIntShort::from_be_bytes(buff))
429 }
430}
431
432pub type CLong = i64;
434
435impl FromCursor for CLong {
436 fn from_cursor(cursor: &mut Cursor<&[u8]>, _version: Version) -> CDRSResult<Self> {
437 let mut buff = [0; LONG_LEN];
438 cursor.read_exact(&mut buff)?;
439
440 Ok(CLong::from_be_bytes(buff))
441 }
442}
443
444impl Serialize for SocketAddr {
445 fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
446 match self.ip() {
447 IpAddr::V4(v4) => {
448 [4].serialize(cursor, version);
449 v4.octets().serialize(cursor, version);
450 }
451 IpAddr::V6(v6) => {
452 [16].serialize(cursor, version);
453 v6.octets().serialize(cursor, version);
454 }
455 }
456
457 to_int(self.port().into()).serialize(cursor, version);
458 }
459}
460
461impl FromCursor for SocketAddr {
462 fn from_cursor(cursor: &mut Cursor<&[u8]>, version: Version) -> CDRSResult<Self> {
463 let mut buff = [0];
464 cursor.read_exact(&mut buff)?;
465
466 let n = buff[0];
467
468 let ip = decode_inet(cursor_next_value(cursor, n as usize)?.as_slice())?;
469 let port = CInt::from_cursor(cursor, version)?;
470 Ok(SocketAddr::new(ip, port as u16))
471 }
472}
473
474pub fn cursor_next_value(cursor: &mut Cursor<&[u8]>, len: usize) -> CDRSResult<Vec<u8>> {
475 let mut buff = vec![0u8; len];
476 cursor.read_exact(&mut buff)?;
477 Ok(buff)
478}
479
480pub fn cursor_next_value_ref<'a>(
481 cursor: &mut Cursor<&'a [u8]>,
482 len: usize,
483) -> CDRSResult<&'a [u8]> {
484 let start = cursor.position() as usize;
485 let result = &cursor.get_ref()[start..start + len];
486 cursor.set_position(cursor.position() + len as u64);
487
488 if result.len() != len {
489 Err(CdrsError::General(
490 "cursor_next_value_ref could not retrieve a full slice".into(),
491 ))
492 } else {
493 Ok(result)
494 }
495}
496
497#[cfg(test)]
498mod tests {
499 use super::*;
500 use crate::frame::traits::FromCursor;
501 use num_bigint::BigInt;
502 use std::io::Cursor;
503
504 fn from_i_bytes(bytes: &[u8]) -> i64 {
505 try_i64_from_bytes(bytes).unwrap()
506 }
507
508 fn try_u16_from_bytes(bytes: &[u8]) -> Result<u16, io::Error> {
509 Ok(u16::from_be_bytes(convert_to_array(bytes)?))
510 }
511
512 fn to_varint(int: BigInt) -> Vec<u8> {
513 int.to_signed_bytes_be()
514 }
515
516 #[test]
517 fn test_from_cursor_str() {
518 let a = &[0, 3, 102, 111, 111, 0];
519 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
520 let cstring = from_cursor_str(&mut cursor).unwrap();
521 assert_eq!(cstring, "foo");
522 }
523
524 #[test]
525 fn test_from_cursor_str_long() {
526 let a = &[0, 0, 0, 3, 102, 111, 111, 0];
527 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
528 let cstring = from_cursor_str_long(&mut cursor).unwrap();
529 assert_eq!(cstring, "foo");
530 }
531
532 #[test]
533 fn test_serialize_str() {
534 let input = "foo";
535
536 let mut buf = vec![];
537 serialize_str(&mut Cursor::new(&mut buf), input, Version::V4);
538
539 assert_eq!(buf, &[0, 3, 102, 111, 111]);
540 }
541
542 #[test]
543 fn test_serialize_str_long() {
544 let input = "foo";
545
546 let mut buf = vec![];
547 serialize_str_long(&mut Cursor::new(&mut buf), input, Version::V4);
548
549 assert_eq!(buf, &[0, 0, 0, 3, 102, 111, 111]);
550 }
551
552 #[test]
553 fn test_cstringlist() {
554 let a = &[0, 2, 0, 3, 102, 111, 111, 0, 3, 102, 111, 112];
555 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
556 let list = from_cursor_string_list(&mut cursor).unwrap();
557
558 assert_eq!(list, vec!("foo".to_string(), "fop".to_string()));
559 }
560
561 #[test]
563 fn test_cbytes_new() {
564 let bytes_vec = vec![1, 2, 3];
565 let _ = CBytes::new(bytes_vec);
566 }
567
568 #[test]
569 fn test_cbytes_into_bytes() {
570 let cbytes = CBytes::new(vec![1, 2, 3]);
571 assert_eq!(cbytes.into_bytes().unwrap(), &[1, 2, 3]);
572 }
573
574 #[test]
575 fn test_cbytes_from_cursor() {
576 let a = &[0, 0, 0, 3, 1, 2, 3];
577 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
578 let cbytes = CBytes::from_cursor(&mut cursor, Version::V4).unwrap();
579 assert_eq!(cbytes.into_bytes().unwrap(), vec![1, 2, 3]);
580 }
581
582 #[test]
583 fn test_cbytes_serialize() {
584 let bytes_vec = vec![1, 2, 3];
585 let cbytes = CBytes::new(bytes_vec);
586 assert_eq!(
587 cbytes.serialize_to_vec(Version::V4),
588 vec![0, 0, 0, 3, 1, 2, 3]
589 );
590 }
591
592 #[test]
594 fn test_cbytesshort_new() {
595 let bytes_vec = vec![1, 2, 3];
596 let _ = CBytesShort::new(bytes_vec);
597 }
598
599 #[test]
600 fn test_cbytesshort_into_bytes() {
601 let cbytes = CBytesShort::new(vec![1, 2, 3]);
602 assert_eq!(cbytes.into_bytes().unwrap(), vec![1, 2, 3]);
603 }
604
605 #[test]
606 fn test_cbytesshort_from_cursor() {
607 let a = &[0, 3, 1, 2, 3];
608 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
609 let cbytes = CBytesShort::from_cursor(&mut cursor, Version::V4).unwrap();
610 assert_eq!(cbytes.into_bytes().unwrap(), vec![1, 2, 3]);
611 }
612
613 #[test]
614 fn test_cbytesshort_serialize() {
615 let bytes_vec: Vec<u8> = vec![1, 2, 3];
616 let cbytes = CBytesShort::new(bytes_vec);
617 assert_eq!(cbytes.serialize_to_vec(Version::V4), vec![0, 3, 1, 2, 3]);
618 }
619
620 #[test]
621 fn test_cint_from_cursor() {
622 let a = &[0, 0, 0, 5];
623 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
624 let i = CInt::from_cursor(&mut cursor, Version::V4).unwrap();
625 assert_eq!(i, 5);
626 }
627
628 #[test]
629 fn test_cintshort_from_cursor() {
630 let a = &[0, 5];
631 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
632 let i = CIntShort::from_cursor(&mut cursor, Version::V4).unwrap();
633 assert_eq!(i, 5);
634 }
635
636 #[test]
637 fn test_cursor_next_value() {
638 let a = &[0, 1, 2, 3, 4];
639 let mut cursor: Cursor<&[u8]> = Cursor::new(a);
640 let l = 3;
641 let val = cursor_next_value(&mut cursor, l).unwrap();
642 assert_eq!(val, vec![0, 1, 2]);
643 }
644
645 #[test]
646 fn test_try_u16_from_bytes() {
647 let bytes: [u8; 2] = [0, 12]; let val = try_u16_from_bytes(&bytes);
649 assert_eq!(val.unwrap(), 12u16);
650 }
651
652 #[test]
653 fn test_from_i_bytes() {
654 let bytes: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 12]; let val = from_i_bytes(&bytes);
656 assert_eq!(val, 12i64);
657 }
658
659 #[test]
660 fn test_to_varint() {
661 assert_eq!(to_varint(0.into()), vec![0x00]);
662 assert_eq!(to_varint(1.into()), vec![0x01]);
663 assert_eq!(to_varint(127.into()), vec![0x7F]);
664 assert_eq!(to_varint(128.into()), vec![0x00, 0x80]);
665 assert_eq!(to_varint(129.into()), vec![0x00, 0x81]);
666 assert_eq!(to_varint(BigInt::from(-1)), vec![0xFF]);
667 assert_eq!(to_varint(BigInt::from(-128)), vec![0x80]);
668 assert_eq!(to_varint(BigInt::from(-129)), vec![0xFF, 0x7F]);
669 }
670}