Skip to content

Commit 5dbb10b

Browse files
authored
Merge pull request #1004 from wprzytula/pre-deserialization-changes
Pre-deserialization-refactor preparatory changes
2 parents e6d8625 + c00ae72 commit 5dbb10b

File tree

11 files changed

+221
-200
lines changed

11 files changed

+221
-200
lines changed

Cargo.lock.msrv

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scylla-cql/Cargo.toml

+10-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ serde = { version = "1.0", features = ["derive"], optional = true }
2828
time = { version = "0.3", optional = true }
2929

3030
[dev-dependencies]
31-
criterion = "0.4" # Note: v0.5 needs at least rust 1.70.0
31+
assert_matches = "1.5.0"
32+
criterion = "0.4" # Note: v0.5 needs at least rust 1.70.0
3233
# Use large-dates feature to test potential edge cases
3334
time = { version = "0.3.21", features = ["large-dates"] }
3435

@@ -43,7 +44,14 @@ chrono = ["dep:chrono"]
4344
num-bigint-03 = ["dep:num-bigint-03"]
4445
num-bigint-04 = ["dep:num-bigint-04"]
4546
bigdecimal-04 = ["dep:bigdecimal-04"]
46-
full-serialization = ["chrono", "time", "secret", "num-bigint-03", "num-bigint-04", "bigdecimal-04"]
47+
full-serialization = [
48+
"chrono",
49+
"time",
50+
"secret",
51+
"num-bigint-03",
52+
"num-bigint-04",
53+
"bigdecimal-04",
54+
]
4755

4856
[lints.rust]
4957
unreachable_pub = "warn"

scylla-cql/src/frame/types.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ fn read_raw_bytes<'a>(count: usize, buf: &mut &'a [u8]) -> Result<&'a [u8], Pars
173173
Ok(ret)
174174
}
175175

176-
pub fn read_int(buf: &mut &[u8]) -> Result<i32, ParseError> {
176+
pub fn read_int(buf: &mut &[u8]) -> Result<i32, std::io::Error> {
177177
let v = buf.read_i32::<BigEndian>()?;
178178
Ok(v)
179179
}
@@ -206,7 +206,7 @@ fn type_int() {
206206
}
207207
}
208208

209-
pub fn read_long(buf: &mut &[u8]) -> Result<i64, ParseError> {
209+
pub fn read_long(buf: &mut &[u8]) -> Result<i64, std::io::Error> {
210210
let v = buf.read_i64::<BigEndian>()?;
211211
Ok(v)
212212
}
@@ -225,7 +225,7 @@ fn type_long() {
225225
}
226226
}
227227

228-
pub fn read_short(buf: &mut &[u8]) -> Result<u16, ParseError> {
228+
pub fn read_short(buf: &mut &[u8]) -> Result<u16, std::io::Error> {
229229
let v = buf.read_u16::<BigEndian>()?;
230230
Ok(v)
231231
}
@@ -234,7 +234,7 @@ pub fn write_short(v: u16, buf: &mut impl BufMut) {
234234
buf.put_u16(v);
235235
}
236236

237-
pub(crate) fn read_short_length(buf: &mut &[u8]) -> Result<usize, ParseError> {
237+
pub(crate) fn read_short_length(buf: &mut &[u8]) -> Result<usize, std::io::Error> {
238238
let v = read_short(buf)?;
239239
let v: usize = v.into();
240240
Ok(v)
@@ -302,11 +302,14 @@ pub fn write_bytes(v: &[u8], buf: &mut impl BufMut) -> Result<(), ParseError> {
302302
Ok(())
303303
}
304304

305-
pub fn write_bytes_opt(v: Option<&Vec<u8>>, buf: &mut impl BufMut) -> Result<(), ParseError> {
305+
pub fn write_bytes_opt(
306+
v: Option<impl AsRef<[u8]>>,
307+
buf: &mut impl BufMut,
308+
) -> Result<(), ParseError> {
306309
match v {
307310
Some(bytes) => {
308-
write_int_length(bytes.len(), buf)?;
309-
buf.put_slice(bytes);
311+
write_int_length(bytes.as_ref().len(), buf)?;
312+
buf.put_slice(bytes.as_ref());
310313
}
311314
None => write_int(-1, buf),
312315
}
@@ -511,9 +514,12 @@ fn type_string_multimap() {
511514
pub fn read_uuid(buf: &mut &[u8]) -> Result<Uuid, ParseError> {
512515
let raw = read_raw_bytes(16, buf)?;
513516

514-
// It's safe to unwrap here because Uuid::from_slice only fails
515-
// if the argument slice's length is not 16.
516-
Ok(Uuid::from_slice(raw).unwrap())
517+
// It's safe to unwrap here because the conversion only fails
518+
// if the argument slice's length does not match, which
519+
// `read_raw_bytes` prevents.
520+
let raw_array: &[u8; 16] = raw.try_into().unwrap();
521+
522+
Ok(Uuid::from_bytes(*raw_array))
517523
}
518524

519525
pub fn write_uuid(uuid: &Uuid, buf: &mut impl BufMut) {
@@ -646,7 +652,7 @@ fn unsigned_vint_encode(v: u64, buf: &mut Vec<u8>) {
646652
buf.put_uint(v, number_of_bytes as usize)
647653
}
648654

649-
fn unsigned_vint_decode(buf: &mut &[u8]) -> Result<u64, ParseError> {
655+
fn unsigned_vint_decode(buf: &mut &[u8]) -> Result<u64, std::io::Error> {
650656
let first_byte = buf.read_u8()?;
651657
let extra_bytes = first_byte.leading_ones() as usize;
652658

@@ -668,7 +674,7 @@ pub(crate) fn vint_encode(v: i64, buf: &mut Vec<u8>) {
668674
unsigned_vint_encode(zig_zag_encode(v), buf)
669675
}
670676

671-
pub(crate) fn vint_decode(buf: &mut &[u8]) -> Result<i64, ParseError> {
677+
pub(crate) fn vint_decode(buf: &mut &[u8]) -> Result<i64, std::io::Error> {
672678
unsigned_vint_decode(buf).map(zig_zag_decode)
673679
}
674680

scylla-cql/src/frame/value_tests.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ use super::value::{
1010
CqlDate, CqlDuration, CqlTime, CqlTimestamp, LegacyBatchValues, LegacySerializedValues,
1111
MaybeUnset, SerializeValuesError, Unset, Value, ValueList, ValueTooBig,
1212
};
13+
#[cfg(test)]
14+
use assert_matches::assert_matches;
1315
use bytes::BufMut;
1416
use std::collections::hash_map::DefaultHasher;
1517
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
@@ -1262,7 +1264,7 @@ fn serialized_values_value_list() {
12621264
ser_values.add_value(&"qwertyuiop").unwrap();
12631265

12641266
let ser_ser_values: Cow<LegacySerializedValues> = ser_values.serialized().unwrap();
1265-
assert!(matches!(ser_ser_values, Cow::Borrowed(_)));
1267+
assert_matches!(ser_ser_values, Cow::Borrowed(_));
12661268

12671269
assert_eq!(&ser_values, ser_ser_values.as_ref());
12681270
}
@@ -1272,7 +1274,7 @@ fn cow_serialized_values_value_list() {
12721274
let cow_ser_values: Cow<LegacySerializedValues> = Cow::Owned(LegacySerializedValues::new());
12731275

12741276
let serialized: Cow<LegacySerializedValues> = cow_ser_values.serialized().unwrap();
1275-
assert!(matches!(serialized, Cow::Borrowed(_)));
1277+
assert_matches!(serialized, Cow::Borrowed(_));
12761278

12771279
assert_eq!(cow_ser_values.as_ref(), serialized.as_ref());
12781280
}

scylla-cql/src/types/serialize/row.rs

+37-42
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ macro_rules! impl_serialize_row_for_unit {
108108
if !ctx.columns().is_empty() {
109109
return Err(mk_typck_err::<Self>(
110110
BuiltinTypeCheckErrorKind::WrongColumnCount {
111-
actual: 0,
112-
asked_for: ctx.columns().len(),
111+
rust_cols: 0,
112+
cql_cols: ctx.columns().len(),
113113
},
114114
));
115115
}
@@ -142,8 +142,8 @@ macro_rules! impl_serialize_row_for_slice {
142142
if ctx.columns().len() != self.len() {
143143
return Err(mk_typck_err::<Self>(
144144
BuiltinTypeCheckErrorKind::WrongColumnCount {
145-
actual: self.len(),
146-
asked_for: ctx.columns().len(),
145+
rust_cols: self.len(),
146+
cql_cols: ctx.columns().len(),
147147
},
148148
));
149149
}
@@ -289,8 +289,8 @@ macro_rules! impl_tuple {
289289
[$($tidents),*] => ($($tidents,)*),
290290
_ => return Err(mk_typck_err::<Self>(
291291
BuiltinTypeCheckErrorKind::WrongColumnCount {
292-
actual: $length,
293-
asked_for: ctx.columns().len(),
292+
rust_cols: $length,
293+
cql_cols: ctx.columns().len(),
294294
},
295295
)),
296296
};
@@ -582,13 +582,13 @@ fn mk_ser_err_named(
582582
#[derive(Debug, Clone)]
583583
#[non_exhaustive]
584584
pub enum BuiltinTypeCheckErrorKind {
585-
/// The Rust type expects `actual` column, but the statement requires `asked_for`.
585+
/// The Rust type provides `rust_cols` columns, but the statement operates on `cql_cols`.
586586
WrongColumnCount {
587587
/// The number of values that the Rust type provides.
588-
actual: usize,
588+
rust_cols: usize,
589589

590-
/// The number of columns that the statement requires.
591-
asked_for: usize,
590+
/// The number of columns that the statement operates on.
591+
cql_cols: usize,
592592
},
593593

594594
/// The Rust type provides a value for some column, but that column is not
@@ -618,8 +618,8 @@ pub enum BuiltinTypeCheckErrorKind {
618618
impl Display for BuiltinTypeCheckErrorKind {
619619
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
620620
match self {
621-
BuiltinTypeCheckErrorKind::WrongColumnCount { actual, asked_for } => {
622-
write!(f, "wrong column count: the query requires {asked_for} columns, but {actual} were provided")
621+
BuiltinTypeCheckErrorKind::WrongColumnCount { rust_cols, cql_cols } => {
622+
write!(f, "wrong column count: the statement operates on {cql_cols} columns, but the given rust type provides {rust_cols}")
623623
}
624624
BuiltinTypeCheckErrorKind::NoColumnWithName { name } => {
625625
write!(
@@ -865,6 +865,7 @@ mod tests {
865865
};
866866

867867
use super::SerializedValues;
868+
use assert_matches::assert_matches;
868869
use scylla_macros::SerializeRow;
869870

870871
fn col_spec(name: &str, typ: ColumnType) -> ColumnSpec {
@@ -1044,13 +1045,13 @@ mod tests {
10441045
let err = do_serialize_err(v, &spec);
10451046
let err = get_typeck_err(&err);
10461047
assert_eq!(err.rust_name, std::any::type_name::<()>());
1047-
assert!(matches!(
1048+
assert_matches!(
10481049
err.kind,
10491050
BuiltinTypeCheckErrorKind::WrongColumnCount {
1050-
actual: 0,
1051-
asked_for: 1,
1051+
rust_cols: 0,
1052+
cql_cols: 1,
10521053
}
1053-
));
1054+
);
10541055

10551056
// Non-unit tuple
10561057
// Count mismatch
@@ -1059,13 +1060,13 @@ mod tests {
10591060
let err = do_serialize_err(v, &spec);
10601061
let err = get_typeck_err(&err);
10611062
assert_eq!(err.rust_name, std::any::type_name::<(&str,)>());
1062-
assert!(matches!(
1063+
assert_matches!(
10631064
err.kind,
10641065
BuiltinTypeCheckErrorKind::WrongColumnCount {
1065-
actual: 1,
1066-
asked_for: 2,
1066+
rust_cols: 1,
1067+
cql_cols: 2,
10671068
}
1068-
));
1069+
);
10691070

10701071
// Serialization of one of the element fails
10711072
let v = ("Ala ma kota", 123_i32);
@@ -1086,13 +1087,13 @@ mod tests {
10861087
let err = do_serialize_err(v, &spec);
10871088
let err = get_typeck_err(&err);
10881089
assert_eq!(err.rust_name, std::any::type_name::<Vec<&str>>());
1089-
assert!(matches!(
1090+
assert_matches!(
10901091
err.kind,
10911092
BuiltinTypeCheckErrorKind::WrongColumnCount {
1092-
actual: 1,
1093-
asked_for: 2,
1093+
rust_cols: 1,
1094+
cql_cols: 2,
10941095
}
1095-
));
1096+
);
10961097

10971098
// Serialization of one of the element fails
10981099
let v = vec!["Ala ma kota", "Kot ma pchły"];
@@ -1214,10 +1215,10 @@ mod tests {
12141215
};
12151216
let err = <_ as SerializeRow>::serialize(&row, &ctx, &mut row_writer).unwrap_err();
12161217
let err = err.0.downcast_ref::<BuiltinTypeCheckError>().unwrap();
1217-
assert!(matches!(
1218+
assert_matches!(
12181219
err.kind,
12191220
BuiltinTypeCheckErrorKind::ValueMissingForColumn { .. }
1220-
));
1221+
);
12211222

12221223
let spec_duplicate_column = [
12231224
col("a", ColumnType::Text),
@@ -1232,10 +1233,7 @@ mod tests {
12321233
};
12331234
let err = <_ as SerializeRow>::serialize(&row, &ctx, &mut row_writer).unwrap_err();
12341235
let err = err.0.downcast_ref::<BuiltinTypeCheckError>().unwrap();
1235-
assert!(matches!(
1236-
err.kind,
1237-
BuiltinTypeCheckErrorKind::NoColumnWithName { .. }
1238-
));
1236+
assert_matches!(err.kind, BuiltinTypeCheckErrorKind::NoColumnWithName { .. });
12391237

12401238
let spec_wrong_type = [
12411239
col("a", ColumnType::Text),
@@ -1248,10 +1246,10 @@ mod tests {
12481246
};
12491247
let err = <_ as SerializeRow>::serialize(&row, &ctx, &mut row_writer).unwrap_err();
12501248
let err = err.0.downcast_ref::<BuiltinSerializationError>().unwrap();
1251-
assert!(matches!(
1249+
assert_matches!(
12521250
err.kind,
12531251
BuiltinSerializationErrorKind::ColumnSerializationFailed { .. }
1254-
));
1252+
);
12551253
}
12561254

12571255
#[derive(SerializeRow)]
@@ -1325,10 +1323,10 @@ mod tests {
13251323
let ctx = RowSerializationContext { columns: &spec };
13261324
let err = <_ as SerializeRow>::serialize(&row, &ctx, &mut writer).unwrap_err();
13271325
let err = err.0.downcast_ref::<BuiltinTypeCheckError>().unwrap();
1328-
assert!(matches!(
1326+
assert_matches!(
13291327
err.kind,
13301328
BuiltinTypeCheckErrorKind::ColumnNameMismatch { .. }
1331-
));
1329+
);
13321330

13331331
let spec_without_c = [
13341332
col("a", ColumnType::Text),
@@ -1341,10 +1339,10 @@ mod tests {
13411339
};
13421340
let err = <_ as SerializeRow>::serialize(&row, &ctx, &mut writer).unwrap_err();
13431341
let err = err.0.downcast_ref::<BuiltinTypeCheckError>().unwrap();
1344-
assert!(matches!(
1342+
assert_matches!(
13451343
err.kind,
13461344
BuiltinTypeCheckErrorKind::ValueMissingForColumn { .. }
1347-
));
1345+
);
13481346

13491347
let spec_duplicate_column = [
13501348
col("a", ColumnType::Text),
@@ -1359,10 +1357,7 @@ mod tests {
13591357
};
13601358
let err = <_ as SerializeRow>::serialize(&row, &ctx, &mut writer).unwrap_err();
13611359
let err = err.0.downcast_ref::<BuiltinTypeCheckError>().unwrap();
1362-
assert!(matches!(
1363-
err.kind,
1364-
BuiltinTypeCheckErrorKind::NoColumnWithName { .. }
1365-
));
1360+
assert_matches!(err.kind, BuiltinTypeCheckErrorKind::NoColumnWithName { .. });
13661361

13671362
let spec_wrong_type = [
13681363
col("a", ColumnType::Text),
@@ -1375,10 +1370,10 @@ mod tests {
13751370
};
13761371
let err = <_ as SerializeRow>::serialize(&row, &ctx, &mut writer).unwrap_err();
13771372
let err = err.0.downcast_ref::<BuiltinSerializationError>().unwrap();
1378-
assert!(matches!(
1373+
assert_matches!(
13791374
err.kind,
13801375
BuiltinSerializationErrorKind::ColumnSerializationFailed { .. }
1381-
));
1376+
);
13821377
}
13831378

13841379
#[test]

0 commit comments

Comments
 (0)