Skip to content

Commit c1f81e4

Browse files
wprzytulapiodul
andcommitted
deser/row: impl DeserializeRow for Row
This implementation is important for two reasons: 1. It enables using the upper layers of the old framework over the new one, which makes the transition smoother. 2. Some users (perhaps ORM users?) are going to need the dynamic capabilities that the previous framework offered: receiving rows consisting of arbitrary number of columns of arbitrary types. This is a perfect use case for Row. Co-authored-by: Piotr Dulikowski <[email protected]>
1 parent 8e0f29a commit c1f81e4

File tree

1 file changed

+37
-1
lines changed
  • scylla-cql/src/types/deserialize

1 file changed

+37
-1
lines changed

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use thiserror::Error;
66

77
use super::value::DeserializeValue;
88
use super::{make_error_replace_rust_name, DeserializationError, FrameSlice, TypeCheckError};
9-
use crate::frame::response::result::{ColumnSpec, ColumnType};
9+
use crate::frame::response::result::{ColumnSpec, ColumnType, CqlValue, Row};
1010

1111
/// Represents a raw, unparsed column value.
1212
#[non_exhaustive]
@@ -135,6 +135,42 @@ make_error_replace_rust_name!(
135135
BuiltinDeserializationError
136136
);
137137

138+
// legacy/dynamic deserialization as Row
139+
//
140+
/// While no longer encouraged (because the new framework encourages deserializing
141+
/// directly into desired types, entirely bypassing CqlValue), this can be indispensable
142+
/// for some use cases, i.e. those involving dynamic parsing (ORMs?).
143+
impl<'frame> DeserializeRow<'frame> for Row {
144+
#[inline]
145+
fn type_check(_specs: &[ColumnSpec]) -> Result<(), TypeCheckError> {
146+
// CqlValues accept all types, no type checking needed.
147+
Ok(())
148+
}
149+
150+
#[inline]
151+
fn deserialize(mut row: ColumnIterator<'frame>) -> Result<Self, DeserializationError> {
152+
let mut columns = Vec::with_capacity(row.size_hint().0);
153+
while let Some(column) = row
154+
.next()
155+
.transpose()
156+
.map_err(deser_error_replace_rust_name::<Self>)?
157+
{
158+
columns.push(
159+
<Option<CqlValue>>::deserialize(&column.spec.typ, column.slice).map_err(|err| {
160+
mk_deser_err::<Self>(
161+
BuiltinDeserializationErrorKind::ColumnDeserializationFailed {
162+
column_index: column.index,
163+
column_name: column.spec.name.clone(),
164+
err,
165+
},
166+
)
167+
})?,
168+
);
169+
}
170+
Ok(Self { columns })
171+
}
172+
}
173+
138174
// tuples
139175
//
140176
/// This is the new encouraged way for deserializing a row.

0 commit comments

Comments
 (0)