Skip to content

Commit d6d3476

Browse files
committed
collection: typecheck value on append
1 parent 4c9beba commit d6d3476

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

scylla-rust-wrapper/src/collection.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use crate::argconv::*;
21
use crate::cass_error::CassError;
32
use crate::cass_types::CassDataType;
43
use crate::types::*;
54
use crate::value::CassCqlValue;
5+
use crate::{argconv::*, value};
66
use std::convert::TryFrom;
77
use std::sync::Arc;
88

@@ -32,8 +32,49 @@ pub struct CassCollection {
3232
}
3333

3434
impl CassCollection {
35+
fn typecheck_on_append(&self, value: &Option<CassCqlValue>) -> CassError {
36+
// See https://github.com/scylladb/cpp-driver/blob/master/src/collection.hpp#L100.
37+
let index = self.items.len();
38+
39+
// Do validation only if it's a typed collection.
40+
if let Some(data_type) = &self.data_type {
41+
match data_type.as_ref() {
42+
CassDataType::List { typ: subtype, .. }
43+
| CassDataType::Set { typ: subtype, .. } => match subtype {
44+
Some(subtype) => {
45+
if !value::is_type_compatible(value, subtype) {
46+
return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE;
47+
}
48+
}
49+
None => {}
50+
},
51+
CassDataType::Map {
52+
key_type: k_typ,
53+
val_type: v_typ,
54+
..
55+
} => {
56+
// Only do the typecheck if both map types are present.
57+
if let (Some(k_typ), Some(v_typ)) = (k_typ, v_typ) {
58+
if index % 2 == 0 && !value::is_type_compatible(value, k_typ) {
59+
return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE;
60+
}
61+
if !value::is_type_compatible(value, v_typ) {
62+
return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE;
63+
}
64+
}
65+
}
66+
_ => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE,
67+
}
68+
}
69+
70+
CassError::CASS_OK
71+
}
72+
3573
pub fn append_cql_value(&mut self, value: Option<CassCqlValue>) -> CassError {
36-
// FIXME: Bounds check, type check
74+
let err = self.typecheck_on_append(&value);
75+
if err != CassError::CASS_OK {
76+
return err;
77+
}
3778
// There is no API to append null, so unwrap is safe
3879
self.items.push(value.unwrap());
3980
CassError::CASS_OK

0 commit comments

Comments
 (0)