11use bytes:: Bytes ;
22use itertools:: Itertools ;
33use lazy_static:: lazy_static;
4- use scylla_cql:: cql_to_rust:: FromCqlVal ;
5- use scylla_cql:: frame:: response:: result:: { deser_cql_value, ColumnType , TableSpec } ;
6- use scylla_cql:: types:: deserialize:: DeserializationError ;
4+ use scylla_cql:: frame:: response:: result:: { ColumnType , TableSpec } ;
5+ use scylla_cql:: types:: deserialize:: value:: ListlikeIterator ;
6+ use scylla_cql:: types:: deserialize:: {
7+ DeserializationError , DeserializeValue , FrameSlice , TypeCheckError ,
8+ } ;
79use thiserror:: Error ;
810use tracing:: warn;
911use uuid:: Uuid ;
@@ -12,12 +14,15 @@ use crate::routing::{Shard, Token};
1214use crate :: transport:: Node ;
1315
1416use std:: collections:: { HashMap , HashSet } ;
17+ use std:: ops:: Deref ;
1518use std:: sync:: Arc ;
1619
1720#[ derive( Error , Debug ) ]
1821pub ( crate ) enum TabletParsingError {
1922 #[ error( transparent) ]
2023 Deserialization ( #[ from] DeserializationError ) ,
24+ #[ error( transparent) ]
25+ TypeCheck ( #[ from] TypeCheckError ) ,
2126 #[ error( "Shard id for tablet is negative: {0}" ) ]
2227 ShardNum ( i32 ) ,
2328}
@@ -36,7 +41,8 @@ pub(crate) struct RawTablet {
3641 replicas : RawTabletReplicas ,
3742}
3843
39- type RawTabletPayload = ( i64 , i64 , Vec < ( Uuid , i32 ) > ) ;
44+ type RawTabletPayload < ' frame , ' metadata > =
45+ ( i64 , i64 , ListlikeIterator < ' frame , ' metadata , ( Uuid , i32 ) > ) ;
4046
4147lazy_static ! {
4248 static ref RAW_TABLETS_CQL_TYPE : ColumnType <' static > = ColumnType :: Tuple ( vec![
@@ -56,26 +62,34 @@ impl RawTablet {
5662 payload : & HashMap < String , Bytes > ,
5763 ) -> Option < Result < RawTablet , TabletParsingError > > {
5864 let payload = payload. get ( CUSTOM_PAYLOAD_TABLETS_V1_KEY ) ?;
59- let cql_value = match deser_cql_value ( & RAW_TABLETS_CQL_TYPE , & mut payload. as_ref ( ) ) {
60- Ok ( r) => r,
61- Err ( e) => return Some ( Err ( e. into ( ) ) ) ,
65+
66+ if let Err ( err) =
67+ <RawTabletPayload as DeserializeValue < ' _ , ' _ > >:: type_check ( RAW_TABLETS_CQL_TYPE . deref ( ) )
68+ {
69+ return Some ( Err ( err. into ( ) ) ) ;
6270 } ;
6371
64- // This could only fail if the type was wrong, but we do pass correct type
65- // to `deser_cql_value`.
6672 let ( first_token, last_token, replicas) : RawTabletPayload =
67- FromCqlVal :: from_cql ( cql_value) . unwrap ( ) ;
73+ match <RawTabletPayload as DeserializeValue < ' _ , ' _ > >:: deserialize (
74+ RAW_TABLETS_CQL_TYPE . deref ( ) ,
75+ Some ( FrameSlice :: new ( payload) ) ,
76+ ) {
77+ Ok ( tuple) => tuple,
78+ Err ( err) => return Some ( Err ( err. into ( ) ) ) ,
79+ } ;
6880
6981 let replicas = match replicas
70- . into_iter ( )
71- . map ( |( uuid, shard_num) | match shard_num. try_into ( ) {
72- Ok ( s) => Ok ( ( uuid, s) ) ,
73- Err ( _) => Err ( shard_num) ,
82+ . map ( |res| {
83+ res. map_err ( TabletParsingError :: from)
84+ . and_then ( |( uuid, shard_num) | match shard_num. try_into ( ) {
85+ Ok ( s) => Ok ( ( uuid, s) ) ,
86+ Err ( _) => Err ( TabletParsingError :: ShardNum ( shard_num) ) ,
87+ } )
7488 } )
75- . collect :: < Result < Vec < ( Uuid , Shard ) > , _ > > ( )
89+ . collect :: < Result < Vec < ( Uuid , Shard ) > , TabletParsingError > > ( )
7690 {
7791 Ok ( r) => r,
78- Err ( shard_num ) => return Some ( Err ( TabletParsingError :: ShardNum ( shard_num ) ) ) ,
92+ Err ( err ) => return Some ( Err ( err ) ) ,
7993 } ;
8094
8195 Some ( Ok ( RawTablet {
0 commit comments