Skip to content

Commit e13bfa9

Browse files
wprzytulapiodul
andcommitted
value: impl DeserializeValue for List and Set
There is a purposeful change from the previous framework: CQL List can no longer be deserialized straight to a HashSet or a BTreeSet. Such deserialization would be lossy, which is a property we don't want in our framework. Co-authored-by: Piotr Dulikowski <[email protected]>
1 parent ebbac62 commit e13bfa9

File tree

2 files changed

+425
-3
lines changed

2 files changed

+425
-3
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,36 @@ impl Display for DeserializationError {
234234
}
235235
}
236236

237+
// This is a hack to enable setting the proper Rust type name in error messages,
238+
// even though the error originates from some helper type used underneath.
239+
// ASSUMPTION: This should be used:
240+
// - ONLY in proper type_check()/deserialize() implementation,
241+
// - BEFORE an error is cloned (because otherwise the Arc::get_mut fails).
242+
macro_rules! make_error_replace_rust_name {
243+
($fn_name: ident, $outer_err: ty, $inner_err: ty) => {
244+
fn $fn_name<RustT>(mut err: $outer_err) -> $outer_err {
245+
// Safety: the assumed usage of this function guarantees that the Arc has not yet been cloned.
246+
let arc_mut = std::sync::Arc::get_mut(&mut err.0).unwrap();
247+
248+
let rust_name: &mut &str = {
249+
if let Some(err) = arc_mut.downcast_mut::<$inner_err>() {
250+
&mut err.rust_name
251+
} else {
252+
unreachable!(concat!(
253+
"This function is assumed to be called only on built-in ",
254+
stringify!($inner_err),
255+
" kinds."
256+
))
257+
}
258+
};
259+
260+
*rust_name = std::any::type_name::<RustT>();
261+
err
262+
}
263+
};
264+
}
265+
use make_error_replace_rust_name;
266+
237267
#[cfg(test)]
238268
mod tests {
239269
use bytes::{Bytes, BytesMut};

0 commit comments

Comments
 (0)