Skip to content

Commit b4ffe3f

Browse files
committed
Implement DeserializeValue for Box<str> and Arc<str>
1 parent 1335392 commit b4ffe3f

File tree

2 files changed

+109
-8
lines changed

2 files changed

+109
-8
lines changed

scylla-cql/src/deserialize/value.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,41 @@ impl<'frame, 'metadata, T: DeserializeValue<'frame, 'metadata>> DeserializeValue
15601560
}
15611561
}
15621562

1563+
// Special cases for Box<str> and Arc<str>
1564+
// The generic implementations above don't work for str. This is because
1565+
// DeserializeValue is implemented for &str, but not for str. We can't change this:
1566+
// the type for DeserializeValue must be Sized because it is returned from deserialize method.
1567+
1568+
impl<'frame, 'metadata> DeserializeValue<'frame, 'metadata> for Box<str> {
1569+
fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1570+
<String as DeserializeValue>::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
1571+
}
1572+
1573+
fn deserialize(
1574+
typ: &'metadata ColumnType<'metadata>,
1575+
v: Option<FrameSlice<'frame>>,
1576+
) -> Result<Self, DeserializationError> {
1577+
String::deserialize(typ, v)
1578+
.map(String::into_boxed_str)
1579+
.map_err(deser_error_replace_rust_name::<Self>)
1580+
}
1581+
}
1582+
1583+
impl<'frame, 'metadata> DeserializeValue<'frame, 'metadata> for Arc<str> {
1584+
fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1585+
<&str as DeserializeValue>::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
1586+
}
1587+
1588+
fn deserialize(
1589+
typ: &'metadata ColumnType<'metadata>,
1590+
v: Option<FrameSlice<'frame>>,
1591+
) -> Result<Self, DeserializationError> {
1592+
<&str as DeserializeValue>::deserialize(typ, v)
1593+
.map(Into::<Arc<str>>::into)
1594+
.map_err(deser_error_replace_rust_name::<Self>)
1595+
}
1596+
}
1597+
15631598
// Utilities
15641599

15651600
fn ensure_not_null_frame_slice<'frame, T>(

scylla-cql/src/deserialize/value_tests.rs

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,18 +1159,36 @@ fn test_tuples() {
11591159

11601160
#[test]
11611161
fn test_box() {
1162-
let int = make_bytes(&[0x01, 0x02, 0x03, 0x04]);
1163-
let decoded_int: Box<i32> =
1164-
deserialize::<Box<i32>>(&ColumnType::Native(NativeType::Int), &int).unwrap();
1165-
assert_eq!(*decoded_int, 0x01020304);
1162+
{
1163+
let int = make_bytes(&[0x01, 0x02, 0x03, 0x04]);
1164+
let decoded_int: Box<i32> =
1165+
deserialize::<Box<i32>>(&ColumnType::Native(NativeType::Int), &int).unwrap();
1166+
assert_eq!(*decoded_int, 0x01020304);
1167+
}
1168+
1169+
{
1170+
let text_bytes = make_bytes(b"abcd");
1171+
let decoded_int: Box<str> =
1172+
deserialize::<Box<str>>(&ColumnType::Native(NativeType::Text), &text_bytes).unwrap();
1173+
assert_eq!(&*decoded_int, "abcd");
1174+
}
11661175
}
11671176

11681177
#[test]
11691178
fn test_arc() {
1170-
let int = make_bytes(&[0x01, 0x02, 0x03, 0x04]);
1171-
let decoded_int: Arc<i32> =
1172-
deserialize::<Arc<i32>>(&ColumnType::Native(NativeType::Int), &int).unwrap();
1173-
assert_eq!(*decoded_int, 0x01020304);
1179+
{
1180+
let int = make_bytes(&[0x01, 0x02, 0x03, 0x04]);
1181+
let decoded_int: Arc<i32> =
1182+
deserialize::<Arc<i32>>(&ColumnType::Native(NativeType::Int), &int).unwrap();
1183+
assert_eq!(*decoded_int, 0x01020304);
1184+
}
1185+
1186+
{
1187+
let text_bytes = make_bytes(b"abcd");
1188+
let decoded_int: Arc<str> =
1189+
deserialize::<Arc<str>>(&ColumnType::Native(NativeType::Text), &text_bytes).unwrap();
1190+
assert_eq!(&*decoded_int, "abcd");
1191+
}
11741192
}
11751193

11761194
pub(crate) fn udt_def_with_fields(
@@ -2489,6 +2507,30 @@ fn test_box_errors() {
24892507
got: 4,
24902508
}
24912509
);
2510+
2511+
// Arc<str> is a special case, let's test it separately
2512+
assert_type_check_error!(
2513+
&bytes,
2514+
Box<str>,
2515+
ColumnType::Native(NativeType::Int),
2516+
BuiltinTypeCheckErrorKind::MismatchedType {
2517+
expected: &[
2518+
ColumnType::Native(NativeType::Ascii),
2519+
ColumnType::Native(NativeType::Text)
2520+
],
2521+
}
2522+
);
2523+
2524+
// -126 is not a valid ASCII nor UTF-8 byte.
2525+
let v = -126_i8;
2526+
let bytes = serialize(&ColumnType::Native(NativeType::TinyInt), &v);
2527+
2528+
assert_deser_error!(
2529+
&bytes,
2530+
Box<str>,
2531+
ColumnType::Native(NativeType::Text),
2532+
BuiltinDeserializationErrorKind::InvalidUtf8(_)
2533+
);
24922534
}
24932535

24942536
#[test]
@@ -2516,6 +2558,30 @@ fn test_arc_errors() {
25162558
got: 4,
25172559
}
25182560
);
2561+
2562+
// Arc<str> is a special case, let's test it separately
2563+
assert_type_check_error!(
2564+
&bytes,
2565+
Arc<str>,
2566+
ColumnType::Native(NativeType::Int),
2567+
BuiltinTypeCheckErrorKind::MismatchedType {
2568+
expected: &[
2569+
ColumnType::Native(NativeType::Ascii),
2570+
ColumnType::Native(NativeType::Text)
2571+
],
2572+
}
2573+
);
2574+
2575+
// -126 is not a valid ASCII nor UTF-8 byte.
2576+
let v = -126_i8;
2577+
let bytes = serialize(&ColumnType::Native(NativeType::TinyInt), &v);
2578+
2579+
assert_deser_error!(
2580+
&bytes,
2581+
Arc<str>,
2582+
ColumnType::Native(NativeType::Text),
2583+
BuiltinDeserializationErrorKind::InvalidUtf8(_)
2584+
);
25192585
}
25202586

25212587
#[test]

0 commit comments

Comments
 (0)