|
1 | | -use std::net::IpAddr; |
| 1 | +use std::{convert::TryInto, net::IpAddr}; |
2 | 2 |
|
3 | 3 | use scylla::{ |
4 | 4 | frame::{response::result::ColumnType, value::CqlDate}, |
5 | 5 | serialize::{ |
6 | 6 | value::{ |
7 | 7 | BuiltinSerializationError, BuiltinSerializationErrorKind, BuiltinTypeCheckError, |
8 | | - BuiltinTypeCheckErrorKind, SerializeCql, TupleSerializationErrorKind, |
9 | | - TupleTypeCheckErrorKind, |
| 8 | + BuiltinTypeCheckErrorKind, SerializeCql, SetOrListSerializationErrorKind, |
| 9 | + SetOrListTypeCheckErrorKind, TupleSerializationErrorKind, TupleTypeCheckErrorKind, |
10 | 10 | }, |
11 | 11 | writers::WrittenCellProof, |
12 | 12 | CellWriter, SerializationError, |
@@ -98,9 +98,9 @@ impl SerializeCql for CassCqlValue { |
98 | 98 | }; |
99 | 99 | serialize_tuple_like(typ, fields.iter(), t.iter(), writer) |
100 | 100 | } |
101 | | - CassCqlValue::List(_) => todo!(), |
| 101 | + CassCqlValue::List(l) => serialize_sequence(l.len(), l.iter(), typ, writer), |
102 | 102 | CassCqlValue::Map(_) => todo!(), |
103 | | - CassCqlValue::Set(_) => todo!(), |
| 103 | + CassCqlValue::Set(s) => serialize_sequence(s.len(), s.iter(), typ, writer), |
104 | 104 | CassCqlValue::UserDefinedType { |
105 | 105 | keyspace, |
106 | 106 | type_name, |
@@ -261,3 +261,48 @@ fn serialize_tuple_like<'t, 'b>( |
261 | 261 | .finish() |
262 | 262 | .map_err(|_| mk_ser_err::<CassCqlValue>(typ, BuiltinSerializationErrorKind::SizeOverflow)) |
263 | 263 | } |
| 264 | + |
| 265 | +fn serialize_sequence<'t, 'b, T: SerializeCql + 't>( |
| 266 | + len: usize, |
| 267 | + iter: impl Iterator<Item = &'t T>, |
| 268 | + typ: &ColumnType, |
| 269 | + writer: CellWriter<'b>, |
| 270 | +) -> Result<WrittenCellProof<'b>, SerializationError> { |
| 271 | + let rust_name = std::any::type_name::<CassCqlValue>(); |
| 272 | + |
| 273 | + let elt = match typ { |
| 274 | + ColumnType::List(elt) | ColumnType::Set(elt) => elt, |
| 275 | + _ => { |
| 276 | + return Err(mk_typck_err_named( |
| 277 | + rust_name, |
| 278 | + typ, |
| 279 | + SetOrListTypeCheckErrorKind::NotSetOrList, |
| 280 | + )); |
| 281 | + } |
| 282 | + }; |
| 283 | + |
| 284 | + let mut builder = writer.into_value_builder(); |
| 285 | + |
| 286 | + let element_count: i32 = len.try_into().map_err(|_| { |
| 287 | + mk_ser_err_named( |
| 288 | + rust_name, |
| 289 | + typ, |
| 290 | + SetOrListSerializationErrorKind::TooManyElements, |
| 291 | + ) |
| 292 | + })?; |
| 293 | + builder.append_bytes(&element_count.to_be_bytes()); |
| 294 | + |
| 295 | + for el in iter { |
| 296 | + T::serialize(el, elt, builder.make_sub_writer()).map_err(|err| { |
| 297 | + mk_ser_err_named( |
| 298 | + rust_name, |
| 299 | + typ, |
| 300 | + SetOrListSerializationErrorKind::ElementSerializationFailed(err), |
| 301 | + ) |
| 302 | + })?; |
| 303 | + } |
| 304 | + |
| 305 | + builder |
| 306 | + .finish() |
| 307 | + .map_err(|_| mk_ser_err_named(rust_name, typ, BuiltinSerializationErrorKind::SizeOverflow)) |
| 308 | +} |
0 commit comments