Skip to content

Commit 4c96bd4

Browse files
authored
Merge pull request #1107 from Lorak-mmk/remove_redundant_macros
Remove redundant macros in response/result.rs
2 parents 4649acb + b1b3b81 commit 4c96bd4

File tree

1 file changed

+161
-141
lines changed

1 file changed

+161
-141
lines changed

scylla-cql/src/frame/response/result.rs

Lines changed: 161 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::cql_to_rust::{FromRow, FromRowError};
22
use crate::frame::frame_errors::{
33
ColumnSpecParseError, ColumnSpecParseErrorKind, CqlResultParseError, CqlTypeParseError,
4-
PreparedParseError, ResultMetadataParseError, RowsParseError, SchemaChangeEventParseError,
5-
SetKeyspaceParseError, TableSpecParseError,
4+
LowLevelDeserializationError, PreparedParseError, ResultMetadataParseError, RowsParseError,
5+
SchemaChangeEventParseError, SetKeyspaceParseError, TableSpecParseError,
66
};
77
use crate::frame::request::query::PagingStateResponse;
88
use crate::frame::response::event::SchemaChangeEvent;
@@ -603,99 +603,104 @@ pub enum Result {
603603
SchemaChange(SchemaChange),
604604
}
605605

606-
macro_rules! generate_deser_type {
607-
($deser_type: ident, $l: lifetime, $read_string: expr) => {
608-
fn $deser_type<'frame>(
609-
buf: &mut &'frame [u8],
610-
) -> StdResult<ColumnType<$l>, CqlTypeParseError> {
611-
use ColumnType::*;
612-
let id = types::read_short(buf)
613-
.map_err(|err| CqlTypeParseError::TypeIdParseError(err.into()))?;
614-
Ok(match id {
615-
0x0000 => {
616-
// We use types::read_string instead of $read_string here on purpose.
617-
// Chances are the underlying string is `...DurationType`, in which case
618-
// we don't need to allocate it at all. Only for Custom types
619-
// (which we don't support anyway) do we need to allocate.
620-
// OTOH, the macro argument function deserializes borrowed OR owned string;
621-
// here we want to always deserialize borrowed string.
622-
let type_str = types::read_string(buf)
623-
.map_err(CqlTypeParseError::CustomTypeNameParseError)?;
624-
match type_str {
625-
"org.apache.cassandra.db.marshal.DurationType" => Duration,
626-
_ => Custom(type_str.to_owned().into()),
627-
}
628-
}
629-
0x0001 => Ascii,
630-
0x0002 => BigInt,
631-
0x0003 => Blob,
632-
0x0004 => Boolean,
633-
0x0005 => Counter,
634-
0x0006 => Decimal,
635-
0x0007 => Double,
636-
0x0008 => Float,
637-
0x0009 => Int,
638-
0x000B => Timestamp,
639-
0x000C => Uuid,
640-
0x000D => Text,
641-
0x000E => Varint,
642-
0x000F => Timeuuid,
643-
0x0010 => Inet,
644-
0x0011 => Date,
645-
0x0012 => Time,
646-
0x0013 => SmallInt,
647-
0x0014 => TinyInt,
648-
0x0015 => Duration,
649-
0x0020 => List(Box::new($deser_type(buf)?)),
650-
0x0021 => Map(Box::new($deser_type(buf)?), Box::new($deser_type(buf)?)),
651-
0x0022 => Set(Box::new($deser_type(buf)?)),
652-
0x0030 => {
653-
let keyspace_name =
654-
$read_string(buf).map_err(CqlTypeParseError::UdtKeyspaceNameParseError)?;
655-
let type_name =
656-
$read_string(buf).map_err(CqlTypeParseError::UdtNameParseError)?;
657-
let fields_size: usize = types::read_short(buf)
658-
.map_err(|err| CqlTypeParseError::UdtFieldsCountParseError(err.into()))?
659-
.into();
660-
661-
let mut field_types: Vec<(Cow<$l, str>, ColumnType)> =
662-
Vec::with_capacity(fields_size);
663-
664-
for _ in 0..fields_size {
665-
let field_name =
666-
$read_string(buf).map_err(CqlTypeParseError::UdtFieldNameParseError)?;
667-
let field_type = $deser_type(buf)?;
668-
669-
field_types.push((field_name.into(), field_type));
670-
}
671-
672-
UserDefinedType {
673-
type_name: type_name.into(),
674-
keyspace: keyspace_name.into(),
675-
field_types,
676-
}
677-
}
678-
0x0031 => {
679-
let len: usize = types::read_short(buf)
680-
.map_err(|err| CqlTypeParseError::TupleLengthParseError(err.into()))?
681-
.into();
682-
let mut types = Vec::with_capacity(len);
683-
for _ in 0..len {
684-
types.push($deser_type(buf)?);
685-
}
686-
Tuple(types)
687-
}
688-
id => {
689-
return Err(CqlTypeParseError::TypeNotImplemented(id));
690-
}
691-
})
606+
fn deser_type_generic<'frame, 'result, StrT: Into<Cow<'result, str>>>(
607+
buf: &mut &'frame [u8],
608+
read_string: fn(&mut &'frame [u8]) -> StdResult<StrT, LowLevelDeserializationError>,
609+
) -> StdResult<ColumnType<'result>, CqlTypeParseError> {
610+
use ColumnType::*;
611+
let id =
612+
types::read_short(buf).map_err(|err| CqlTypeParseError::TypeIdParseError(err.into()))?;
613+
Ok(match id {
614+
0x0000 => {
615+
// We use types::read_string instead of read_string argument here on purpose.
616+
// Chances are the underlying string is `...DurationType`, in which case
617+
// we don't need to allocate it at all. Only for Custom types
618+
// (which we don't support anyway) do we need to allocate.
619+
// OTOH, the macro argument function deserializes borrowed OR owned string;
620+
// here we want to always deserialize borrowed string.
621+
let type_str =
622+
types::read_string(buf).map_err(CqlTypeParseError::CustomTypeNameParseError)?;
623+
match type_str {
624+
"org.apache.cassandra.db.marshal.DurationType" => Duration,
625+
_ => Custom(type_str.to_owned().into()),
626+
}
692627
}
693-
};
628+
0x0001 => Ascii,
629+
0x0002 => BigInt,
630+
0x0003 => Blob,
631+
0x0004 => Boolean,
632+
0x0005 => Counter,
633+
0x0006 => Decimal,
634+
0x0007 => Double,
635+
0x0008 => Float,
636+
0x0009 => Int,
637+
0x000B => Timestamp,
638+
0x000C => Uuid,
639+
0x000D => Text,
640+
0x000E => Varint,
641+
0x000F => Timeuuid,
642+
0x0010 => Inet,
643+
0x0011 => Date,
644+
0x0012 => Time,
645+
0x0013 => SmallInt,
646+
0x0014 => TinyInt,
647+
0x0015 => Duration,
648+
0x0020 => List(Box::new(deser_type_generic(buf, read_string)?)),
649+
0x0021 => Map(
650+
Box::new(deser_type_generic(buf, read_string)?),
651+
Box::new(deser_type_generic(buf, read_string)?),
652+
),
653+
0x0022 => Set(Box::new(deser_type_generic(buf, read_string)?)),
654+
0x0030 => {
655+
let keyspace_name =
656+
read_string(buf).map_err(CqlTypeParseError::UdtKeyspaceNameParseError)?;
657+
let type_name = read_string(buf).map_err(CqlTypeParseError::UdtNameParseError)?;
658+
let fields_size: usize = types::read_short(buf)
659+
.map_err(|err| CqlTypeParseError::UdtFieldsCountParseError(err.into()))?
660+
.into();
661+
662+
let mut field_types: Vec<(Cow<'result, str>, ColumnType)> =
663+
Vec::with_capacity(fields_size);
664+
665+
for _ in 0..fields_size {
666+
let field_name =
667+
read_string(buf).map_err(CqlTypeParseError::UdtFieldNameParseError)?;
668+
let field_type = deser_type_generic(buf, read_string)?;
669+
670+
field_types.push((field_name.into(), field_type));
671+
}
672+
673+
UserDefinedType {
674+
type_name: type_name.into(),
675+
keyspace: keyspace_name.into(),
676+
field_types,
677+
}
678+
}
679+
0x0031 => {
680+
let len: usize = types::read_short(buf)
681+
.map_err(|err| CqlTypeParseError::TupleLengthParseError(err.into()))?
682+
.into();
683+
let mut types = Vec::with_capacity(len);
684+
for _ in 0..len {
685+
types.push(deser_type_generic(buf, read_string)?);
686+
}
687+
Tuple(types)
688+
}
689+
id => {
690+
return Err(CqlTypeParseError::TypeNotImplemented(id));
691+
}
692+
})
694693
}
695694

696-
generate_deser_type!(_deser_type_borrowed, 'frame, types::read_string);
695+
fn _deser_type_borrowed<'frame>(
696+
buf: &mut &'frame [u8],
697+
) -> StdResult<ColumnType<'frame>, CqlTypeParseError> {
698+
deser_type_generic(buf, |buf| types::read_string(buf))
699+
}
697700

698-
generate_deser_type!(deser_type_owned, 'static, |buf| types::read_string(buf).map(ToOwned::to_owned));
701+
fn deser_type_owned(buf: &mut &[u8]) -> StdResult<ColumnType<'static>, CqlTypeParseError> {
702+
deser_type_generic(buf, |buf| types::read_string(buf).map(ToOwned::to_owned))
703+
}
699704

700705
/// Deserializes a table spec, be it per-column one or a global one,
701706
/// in the borrowed form.
@@ -775,58 +780,73 @@ fn deser_table_spec_for_col_spec<'frame>(
775780
Ok(table_spec)
776781
}
777782

778-
macro_rules! generate_deser_col_specs {
779-
($deser_col_specs: ident, $l: lifetime, $deser_type: ident, $make_col_spec: expr $(,)?) => {
780-
/// Deserializes col specs (part of ResultMetadata or PreparedMetadata)
781-
/// in the form mentioned by its name.
782-
///
783-
/// Checks for equality of table specs across columns, because the protocol
784-
/// does not guarantee that and we want to be sure that the assumption
785-
/// of them being all the same is correct.
786-
///
787-
/// To avoid needless allocations, it is advised to pass `global_table_spec`
788-
/// in the borrowed form, so that cloning it is cheap.
789-
fn $deser_col_specs<'frame>(
790-
buf: &mut &'frame [u8],
791-
global_table_spec: Option<TableSpec<'frame>>,
792-
col_count: usize,
793-
) -> StdResult<Vec<ColumnSpec<$l>>, ColumnSpecParseError> {
794-
let global_table_spec_provided = global_table_spec.is_some();
795-
let mut known_table_spec = global_table_spec;
796-
797-
let mut col_specs = Vec::with_capacity(col_count);
798-
for col_idx in 0..col_count {
799-
let table_spec = deser_table_spec_for_col_spec(
800-
buf,
801-
global_table_spec_provided,
802-
&mut known_table_spec,
803-
col_idx,
804-
)?;
805-
806-
let name =
807-
types::read_string(buf).map_err(|err| mk_col_spec_parse_error(col_idx, err))?;
808-
let typ = $deser_type(buf).map_err(|err| mk_col_spec_parse_error(col_idx, err))?;
809-
let col_spec = $make_col_spec(name, typ, table_spec);
810-
col_specs.push(col_spec);
811-
}
812-
Ok(col_specs)
813-
}
814-
};
783+
/// Deserializes col specs (part of ResultMetadata or PreparedMetadata)
784+
/// in the form mentioned by its name.
785+
///
786+
/// Checks for equality of table specs across columns, because the protocol
787+
/// does not guarantee that and we want to be sure that the assumption
788+
/// of them being all the same is correct.
789+
///
790+
/// To avoid needless allocations, it is advised to pass `global_table_spec`
791+
/// in the borrowed form, so that cloning it is cheap.
792+
fn deser_col_specs_generic<'frame, 'result>(
793+
buf: &mut &'frame [u8],
794+
global_table_spec: Option<TableSpec<'frame>>,
795+
col_count: usize,
796+
make_col_spec: fn(&'frame str, ColumnType<'result>, TableSpec<'frame>) -> ColumnSpec<'result>,
797+
deser_type: fn(&mut &'frame [u8]) -> StdResult<ColumnType<'result>, CqlTypeParseError>,
798+
) -> StdResult<Vec<ColumnSpec<'result>>, ColumnSpecParseError> {
799+
let global_table_spec_provided = global_table_spec.is_some();
800+
let mut known_table_spec = global_table_spec;
801+
802+
let mut col_specs = Vec::with_capacity(col_count);
803+
for col_idx in 0..col_count {
804+
let table_spec = deser_table_spec_for_col_spec(
805+
buf,
806+
global_table_spec_provided,
807+
&mut known_table_spec,
808+
col_idx,
809+
)?;
810+
811+
let name = types::read_string(buf).map_err(|err| mk_col_spec_parse_error(col_idx, err))?;
812+
let typ = deser_type(buf).map_err(|err| mk_col_spec_parse_error(col_idx, err))?;
813+
let col_spec = make_col_spec(name, typ, table_spec);
814+
col_specs.push(col_spec);
815+
}
816+
Ok(col_specs)
817+
}
818+
819+
fn _deser_col_specs_borrowed<'frame>(
820+
buf: &mut &'frame [u8],
821+
global_table_spec: Option<TableSpec<'frame>>,
822+
col_count: usize,
823+
) -> StdResult<Vec<ColumnSpec<'frame>>, ColumnSpecParseError> {
824+
deser_col_specs_generic(
825+
buf,
826+
global_table_spec,
827+
col_count,
828+
ColumnSpec::borrowed,
829+
_deser_type_borrowed,
830+
)
815831
}
816832

817-
generate_deser_col_specs!(
818-
_deser_col_specs_borrowed,
819-
'frame,
820-
_deser_type_borrowed,
821-
ColumnSpec::borrowed,
822-
);
823-
824-
generate_deser_col_specs!(
825-
deser_col_specs_owned,
826-
'static,
827-
deser_type_owned,
828-
|name: &str, typ, table_spec: TableSpec| ColumnSpec::owned(name.to_owned(), typ, table_spec.into_owned()),
829-
);
833+
fn deser_col_specs_owned<'frame>(
834+
buf: &mut &'frame [u8],
835+
global_table_spec: Option<TableSpec<'frame>>,
836+
col_count: usize,
837+
) -> StdResult<Vec<ColumnSpec<'static>>, ColumnSpecParseError> {
838+
let result: StdResult<Vec<ColumnSpec<'static>>, ColumnSpecParseError> = deser_col_specs_generic(
839+
buf,
840+
global_table_spec,
841+
col_count,
842+
|name: &str, typ, table_spec: TableSpec| {
843+
ColumnSpec::owned(name.to_owned(), typ, table_spec.into_owned())
844+
},
845+
deser_type_owned,
846+
);
847+
848+
result
849+
}
830850

831851
fn deser_result_metadata(
832852
buf: &mut &[u8],

0 commit comments

Comments
 (0)