Skip to content

Commit 7854229

Browse files
committed
test: metadata does not bound deserialized values
This commit introduced a test, whose goal is to assert in compile time (by satisfying the borrow checker) that deserialized values are not bound by the lifetime of the metadata (the column type).
1 parent 78fc453 commit 7854229

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

scylla-cql/src/types/deserialize/value_tests.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use assert_matches::assert_matches;
22
use bytes::{BufMut, Bytes, BytesMut};
3+
use scylla_macros::DeserializeValue;
34
use uuid::Uuid;
45

56
use std::borrow::Cow;
@@ -1960,3 +1961,76 @@ fn test_udt_errors() {
19601961
}
19611962
}
19621963
}
1964+
1965+
#[test]
1966+
fn metadata_does_not_bound_deserialized_values() {
1967+
/* It's important to understand what is a _deserialized value_. It's not just
1968+
* an implementor of DeserializeValue; there are some implementors of DeserializeValue
1969+
* who are not yet final values, but partially deserialized types that support further
1970+
* deserialization - _value deserializers_, such as `ListlikeIterator` or `UdtIterator`.
1971+
* _Value deserializers_, because they still need to deserialize some value, are naturally
1972+
* bound by 'metadata lifetime. However, _values_ are completely deserialized, so they
1973+
* should not be bound by 'metadata - only by 'frame. This test asserts that.
1974+
*/
1975+
1976+
// We don't care about the actual deserialized data - all `Err`s is OK.
1977+
// This test's goal is only to compile, asserting that lifetimes are correct.
1978+
let bytes = Bytes::new();
1979+
1980+
// By this binding, we require that the deserialized values live longer than metadata.
1981+
let _decoded_results = {
1982+
// Metadata's lifetime is limited to this scope.
1983+
1984+
// blob
1985+
let blob_typ = ColumnType::Blob;
1986+
let decoded_blob_res = deserialize::<&[u8]>(&blob_typ, &bytes);
1987+
1988+
// str
1989+
let str_typ = ColumnType::Ascii;
1990+
let decoded_str_res = deserialize::<&str>(&str_typ, &bytes);
1991+
1992+
// list
1993+
let list_typ = ColumnType::List(Box::new(ColumnType::Ascii));
1994+
let decoded_vec_str_res = deserialize::<Vec<&str>>(&list_typ, &bytes);
1995+
let decoded_vec_string_res = deserialize::<Vec<String>>(&list_typ, &bytes);
1996+
1997+
// set
1998+
let set_typ = ColumnType::Set(Box::new(ColumnType::Ascii));
1999+
let decoded_set_str_res = deserialize::<HashSet<&str>>(&set_typ, &bytes);
2000+
let decoded_set_string_res = deserialize::<HashSet<String>>(&set_typ, &bytes);
2001+
2002+
// map
2003+
let map_typ = ColumnType::Map(Box::new(ColumnType::Ascii), Box::new(ColumnType::Int));
2004+
let decoded_map_str_int_res = deserialize::<HashMap<&str, i32>>(&map_typ, &bytes);
2005+
2006+
// UDT
2007+
let udt_typ = ColumnType::UserDefinedType {
2008+
type_name: "udt".into(),
2009+
keyspace: "ks".into(),
2010+
field_types: vec![
2011+
("bytes".into(), ColumnType::Blob),
2012+
("text".into(), ColumnType::Text),
2013+
],
2014+
};
2015+
#[derive(DeserializeValue)]
2016+
#[scylla(crate=crate)]
2017+
struct Udt<'frame> {
2018+
#[allow(dead_code)]
2019+
bytes: &'frame [u8],
2020+
#[allow(dead_code)]
2021+
text: &'frame str,
2022+
}
2023+
let decoded_udt_res = deserialize::<Udt>(&udt_typ, &bytes);
2024+
2025+
(
2026+
decoded_blob_res,
2027+
decoded_str_res,
2028+
decoded_vec_str_res,
2029+
decoded_vec_string_res,
2030+
decoded_set_str_res,
2031+
decoded_set_string_res,
2032+
decoded_map_str_int_res,
2033+
decoded_udt_res,
2034+
)
2035+
};
2036+
}

0 commit comments

Comments
 (0)