Skip to content

Commit 480c5d3

Browse files
authored
Merge pull request #1379 from Lorak-mmk/fix-deserialize-renaming
Fix deserialize renaming
2 parents 6a38368 + a868920 commit 480c5d3

File tree

4 files changed

+260
-106
lines changed

4 files changed

+260
-106
lines changed

scylla-cql/src/deserialize/mod.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -295,27 +295,30 @@ impl DeserializationError {
295295
// - ONLY in proper type_check()/deserialize() implementation,
296296
// - BEFORE an error is cloned (because otherwise the Arc::get_mut fails).
297297
macro_rules! make_error_replace_rust_name {
298-
($privacy: vis, $fn_name: ident, $outer_err: ty, $inner_err: ty) => {
298+
($privacy: vis, $fn_name: ident, $outer_err: ty, $inner_err: ident) => {
299299
// Not part of the public API; used in derive macros.
300300
#[doc(hidden)]
301301
#[allow(clippy::needless_pub_self)]
302302
$privacy fn $fn_name<RustT>(mut err: $outer_err) -> $outer_err {
303-
// Safety: the assumed usage of this function guarantees that the Arc has not yet been cloned.
304-
let arc_mut = std::sync::Arc::get_mut(&mut err.0).unwrap();
305-
306-
let rust_name: &mut &str = {
307-
if let Some(err) = arc_mut.downcast_mut::<$inner_err>() {
308-
&mut err.rust_name
309-
} else {
310-
unreachable!(concat!(
311-
"This function is assumed to be called only on built-in ",
312-
stringify!($inner_err),
313-
" kinds."
314-
))
303+
let rust_name = std::any::type_name::<RustT>();
304+
match std::sync::Arc::get_mut(&mut err.0) {
305+
Some(arc_mut) => {
306+
if let Some(err) = arc_mut.downcast_mut::<$inner_err>() {
307+
err.rust_name = rust_name;
308+
}
309+
},
310+
None => {
311+
if let Some(err) = err.0.downcast_ref::<$inner_err>() {
312+
if err.rust_name != rust_name {
313+
return <$outer_err>::new($inner_err {
314+
rust_name,
315+
..err.clone()
316+
});
317+
}
318+
}
315319
}
316-
};
320+
}
317321

318-
*rust_name = std::any::type_name::<RustT>();
319322
err
320323
}
321324
};

scylla-cql/src/deserialize/row_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ fn test_row_errors() {
426426
};
427427
assert_eq!(column_name, col_name);
428428
let err = super::super::value::tests::get_deser_err(err);
429-
assert_eq!(err.rust_name, std::any::type_name::<CqlValue>());
429+
assert_eq!(err.rust_name, std::any::type_name::<Option<CqlValue>>());
430430
assert_eq!(err.cql_type, ColumnType::Native(NativeType::BigInt));
431431
let super::super::value::BuiltinDeserializationErrorKind::ByteLengthMismatch {
432432
expected: 8,
@@ -883,7 +883,7 @@ fn test_struct_deserialization_errors() {
883883
assert_eq!(column_name.as_str(), "b");
884884
assert_eq!(field_index, 2);
885885
let err = value::tests::get_deser_err(err);
886-
assert_eq!(err.rust_name, std::any::type_name::<i32>());
886+
assert_eq!(err.rust_name, std::any::type_name::<Option<i32>>());
887887
assert_eq!(err.cql_type, ColumnType::Native(NativeType::Int));
888888
assert_matches!(
889889
err.kind,

scylla-cql/src/deserialize/value.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,16 @@ where
7979
T: DeserializeValue<'frame, 'metadata>,
8080
{
8181
fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
82-
T::type_check(typ)
82+
T::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
8383
}
8484

8585
fn deserialize(
8686
typ: &'metadata ColumnType<'metadata>,
8787
v: Option<FrameSlice<'frame>>,
8888
) -> Result<Self, DeserializationError> {
89-
v.map(|_| T::deserialize(typ, v)).transpose()
89+
v.map(|_| T::deserialize(typ, v))
90+
.transpose()
91+
.map_err(deser_error_replace_rust_name::<Self>)
9092
}
9193
}
9294

@@ -118,6 +120,7 @@ where
118120
#[inline]
119121
fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
120122
<T as DeserializeValue<'frame, 'metadata>>::type_check(typ)
123+
.map_err(typck_error_replace_rust_name::<Self>)
121124
}
122125

123126
fn deserialize(
@@ -128,7 +131,8 @@ where
128131
if val.is_empty() {
129132
Ok(MaybeEmpty::Empty)
130133
} else {
131-
let v = <T as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v)?;
134+
let v = <T as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v)
135+
.map_err(deser_error_replace_rust_name::<Self>)?;
132136
Ok(MaybeEmpty::Value(v))
133137
}
134138
}
@@ -662,13 +666,16 @@ where
662666
{
663667
fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
664668
<T as DeserializeValue<'frame, 'metadata>>::type_check(typ)
669+
.map_err(typck_error_replace_rust_name::<Self>)
665670
}
666671

667672
fn deserialize(
668673
typ: &'metadata ColumnType<'metadata>,
669674
v: Option<FrameSlice<'frame>>,
670675
) -> Result<Self, DeserializationError> {
671-
<T as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v).map(secrecy_08::Secret::new)
676+
<T as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v)
677+
.map(secrecy_08::Secret::new)
678+
.map_err(deser_error_replace_rust_name::<Self>)
672679
}
673680
}
674681

@@ -691,6 +698,7 @@ make_error_replace_rust_name!(
691698
// lists and sets
692699

693700
/// An iterator over either a CQL set or list.
701+
#[derive(Debug, Clone)]
694702
pub struct ListlikeIterator<'frame, 'metadata, T> {
695703
coll_typ: &'metadata ColumnType<'metadata>,
696704
elem_typ: &'metadata ColumnType<'metadata>,
@@ -873,8 +881,8 @@ where
873881
match typ {
874882
ColumnType::Collection {
875883
frozen: false,
876-
typ: CollectionType::Set(el_t),
877-
} => <T as DeserializeValue<'frame, 'metadata>>::type_check(el_t)
884+
typ: CollectionType::Set(_),
885+
} => ListlikeIterator::<'frame, 'metadata, T>::type_check(typ)
878886
.map_err(typck_error_replace_rust_name::<Self>),
879887
_ => Err(mk_typck_err::<Self>(
880888
typ,
@@ -904,8 +912,8 @@ where
904912
match typ {
905913
ColumnType::Collection {
906914
frozen: false,
907-
typ: CollectionType::Set(el_t),
908-
} => <T as DeserializeValue<'frame, 'metadata>>::type_check(el_t)
915+
typ: CollectionType::Set(_),
916+
} => ListlikeIterator::<'frame, 'metadata, T>::type_check(typ)
909917
.map_err(typck_error_replace_rust_name::<Self>),
910918
_ => Err(mk_typck_err::<Self>(
911919
typ,
@@ -943,6 +951,7 @@ where
943951
/// It would be nice to have a rule to determine if the element type is fixed-length or not,
944952
/// however, we only have a heuristic. There are a few types that should, for all intents and purposes,
945953
/// be considered fixed-length, but are not, e.g TinyInt. See ColumnType::type_size() for the list.
954+
#[derive(Debug, Clone)]
946955
pub struct VectorIterator<'frame, 'metadata, T> {
947956
collection_type: &'metadata ColumnType<'metadata>,
948957
element_type: &'metadata ColumnType<'metadata>,
@@ -1101,6 +1110,7 @@ where
11011110
}
11021111

11031112
/// An iterator over a CQL map.
1113+
#[derive(Debug, Clone)]
11041114
pub struct MapIterator<'frame, 'metadata, K, V> {
11051115
coll_typ: &'metadata ColumnType<'metadata>,
11061116
k_typ: &'metadata ColumnType<'metadata>,
@@ -1416,6 +1426,7 @@ impl_tuple_multiple!(
14161426
/// - `None` - missing from the serialized form
14171427
/// - `Some(None)` - present, but null
14181428
/// - `Some(Some(...))` - non-null, present value
1429+
#[derive(Debug, Clone)]
14191430
pub struct UdtIterator<'frame, 'metadata> {
14201431
all_fields: &'metadata [(Cow<'metadata, str>, ColumnType<'metadata>)],
14211432
type_name: &'metadata str,
@@ -1990,7 +2001,7 @@ impl Display for UdtTypeCheckErrorKind {
19902001
}
19912002

19922003
/// Deserialization of one of the built-in types failed.
1993-
#[derive(Debug, Error)]
2004+
#[derive(Debug, Error, Clone)]
19942005
#[error("Failed to deserialize Rust type {rust_name} from CQL type {cql_type:?}: {kind}")]
19952006
pub struct BuiltinDeserializationError {
19962007
/// Name of the Rust type being deserialized.
@@ -2025,7 +2036,7 @@ fn mk_deser_err_named(
20252036
}
20262037

20272038
/// Describes why deserialization of some of the built-in types failed.
2028-
#[derive(Debug)]
2039+
#[derive(Debug, Clone)]
20292040
#[non_exhaustive]
20302041
pub enum BuiltinDeserializationErrorKind {
20312042
/// Failed to deserialize one of date's fields.
@@ -2118,7 +2129,7 @@ impl Display for BuiltinDeserializationErrorKind {
21182129
}
21192130

21202131
/// Describes why deserialization of a set or list type failed.
2121-
#[derive(Debug)]
2132+
#[derive(Debug, Clone)]
21222133
#[non_exhaustive]
21232134
pub enum SetOrListDeserializationErrorKind {
21242135
/// Failed to deserialize set or list's length.
@@ -2149,7 +2160,7 @@ impl From<SetOrListDeserializationErrorKind> for BuiltinDeserializationErrorKind
21492160
}
21502161

21512162
/// Describes why deserialization of a vector type failed.
2152-
#[derive(Error, Debug)]
2163+
#[derive(Error, Debug, Clone)]
21532164
#[non_exhaustive]
21542165
pub enum VectorDeserializationErrorKind {
21552166
/// One of the elements of the vector failed to deserialize.
@@ -2165,7 +2176,7 @@ impl From<VectorDeserializationErrorKind> for BuiltinDeserializationErrorKind {
21652176
}
21662177

21672178
/// Describes why deserialization of a map type failed.
2168-
#[derive(Debug)]
2179+
#[derive(Debug, Clone)]
21692180
#[non_exhaustive]
21702181
// Check triggers because all variants end with "DeserializationFailed".
21712182
// TODO(2.0): Remove the "DeserializationFailed" postfix from variants.

0 commit comments

Comments
 (0)