Skip to content

Commit

Permalink
test: metadata does not bound deserialized rows
Browse files Browse the repository at this point in the history
This commit introduced a test, whose goal is to assert in compile time
(by satisfying the borrow checker) that deserialized rows are not
bound by the lifetime of the metadata (the column specs).
  • Loading branch information
wprzytula committed Oct 25, 2024
1 parent 2fcc313 commit c4ba720
Showing 1 changed file with 47 additions and 1 deletion.
48 changes: 47 additions & 1 deletion scylla-cql/src/types/deserialize/row_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use assert_matches::assert_matches;
use bytes::Bytes;
use scylla_macros::DeserializeRow;

use crate::frame::response::result::{ColumnSpec, ColumnType};
use crate::frame::response::result::{ColumnSpec, ColumnType, TableSpec};
use crate::types::deserialize::row::BuiltinDeserializationErrorKind;
use crate::types::deserialize::{value, DeserializationError, FrameSlice};

Expand Down Expand Up @@ -859,3 +859,49 @@ fn test_struct_deserialization_errors() {
}
}
}

#[test]
fn metadata_does_not_bound_deserialized_rows() {
/* It's important to understand what is a _deserialized row_. It's not just
* an implementor of `DeserializeRow`; there are some implementors of `DeserializeRow`
* who are not yet final rows, but partially deserialized rows that support further
* deserialization - _row deserializers_, such as `ColumnIterator`.
* _Row deserializers_, because they still need to deserialize some row, are naturally
* bound by 'metadata lifetime. However, _rows_ are completely deserialized, so they
* should not be bound by 'metadata - only by 'frame. This test asserts that.
*/

// We don't care about the actual deserialized data - all `Err`s is OK.
// This test's goal is only to compile, asserting that lifetimes are correct.
let bytes = Bytes::new();

// By this binding, we require that the deserialized rows live longer than metadata.
let _decoded_results = {
// Metadata's lifetime is limited to this scope.

fn col_spec<'a>(name: &'a str, typ: ColumnType<'a>) -> ColumnSpec<'a> {
ColumnSpec::borrowed(name, typ, TableSpec::borrowed("ks", "tbl"))
}

let row_typ = &[
col_spec("bytes", ColumnType::Blob),
col_spec("text", ColumnType::Text),
];

// Tuple
let decoded_tuple_res = deserialize::<(&[u8], &str)>(row_typ, &bytes);

// Custom struct
#[derive(DeserializeRow)]
#[scylla(crate=crate)]
struct MyRow<'frame> {
#[allow(dead_code)]
bytes: &'frame [u8],
#[allow(dead_code)]
text: &'frame str,
}
let decoded_custom_struct_res = deserialize::<MyRow>(row_typ, &bytes);

(decoded_tuple_res, decoded_custom_struct_res)
};
}

0 comments on commit c4ba720

Please sign in to comment.