@@ -131,6 +131,13 @@ impl Default for UDTDataType {
131131 }
132132}
133133
134+ #[ derive( Clone , Debug , PartialEq ) ]
135+ pub enum MapDataType {
136+ Untyped ,
137+ Key ( Arc < CassDataType > ) ,
138+ KeyAndValue ( Arc < CassDataType > , Arc < CassDataType > ) ,
139+ }
140+
134141#[ derive( Clone , Debug , PartialEq ) ]
135142pub enum CassDataType {
136143 Value ( CassValueType ) ,
@@ -146,10 +153,7 @@ pub enum CassDataType {
146153 frozen : bool ,
147154 } ,
148155 Map {
149- // None, None stands for untyped map.
150- // Some, None stands for a map with an untyped value type.
151- key_type : Option < Arc < CassDataType > > ,
152- val_type : Option < Arc < CassDataType > > ,
156+ typ : MapDataType ,
153157 frozen : bool ,
154158 } ,
155159 // Empty vector stands for untyped tuple.
@@ -183,29 +187,22 @@ impl CassDataType {
183187 }
184188 _ => false ,
185189 } ,
186- CassDataType :: Map {
187- key_type : k,
188- val_type : v,
189- ..
190- } => match other {
191- CassDataType :: Map {
192- key_type : k_other,
193- val_type : v_other,
194- ..
195- } => match ( ( k, v) , ( k_other, v_other) ) {
190+ CassDataType :: Map { typ : t, .. } => match other {
191+ CassDataType :: Map { typ : t_other, .. } => match ( t, t_other) {
196192 // See https://github.com/scylladb/cpp-driver/blob/master/src/data_type.hpp#L218
197193 // In cpp-driver the types are held in a vector.
198194 // The logic is following:
199195
200196 // If either of vectors is empty, skip the typecheck.
201- ( ( None , None ) , _) => true ,
202- ( _, ( None , None ) ) => true ,
197+ ( MapDataType :: Untyped , _) => true ,
198+ ( _, MapDataType :: Untyped ) => true ,
203199
204200 // Otherwise, the vectors should have equal length and we perform the typecheck for subtypes.
205- ( ( Some ( k) , None ) , ( Some ( k_other) , None ) ) => k. typecheck_equals ( k_other) ,
206- ( ( Some ( k) , Some ( v) ) , ( Some ( k_other) , Some ( v_other) ) ) => {
207- k. typecheck_equals ( k_other) && v. typecheck_equals ( v_other)
208- }
201+ ( MapDataType :: Key ( k) , MapDataType :: Key ( k_other) ) => k. typecheck_equals ( k_other) ,
202+ (
203+ MapDataType :: KeyAndValue ( k, v) ,
204+ MapDataType :: KeyAndValue ( k_other, v_other) ,
205+ ) => k. typecheck_equals ( k_other) && v. typecheck_equals ( v_other) ,
209206 _ => false ,
210207 } ,
211208 _ => false ,
@@ -276,16 +273,18 @@ pub fn get_column_type_from_cql_type(
276273 frozen : * frozen,
277274 } ,
278275 CollectionType :: Map ( key, value) => CassDataType :: Map {
279- key_type : Some ( Arc :: new ( get_column_type_from_cql_type (
280- key,
281- user_defined_types,
282- keyspace_name,
283- ) ) ) ,
284- val_type : Some ( Arc :: new ( get_column_type_from_cql_type (
285- value,
286- user_defined_types,
287- keyspace_name,
288- ) ) ) ,
276+ typ : MapDataType :: KeyAndValue (
277+ Arc :: new ( get_column_type_from_cql_type (
278+ key,
279+ user_defined_types,
280+ keyspace_name,
281+ ) ) ,
282+ Arc :: new ( get_column_type_from_cql_type (
283+ value,
284+ user_defined_types,
285+ keyspace_name,
286+ ) ) ,
287+ ) ,
289288 frozen : * frozen,
290289 } ,
291290 CollectionType :: Set ( set) => CassDataType :: Set {
@@ -338,10 +337,19 @@ impl CassDataType {
338337 }
339338 }
340339 CassDataType :: Map {
341- key_type, val_type, ..
340+ typ : MapDataType :: Untyped ,
341+ ..
342+ } => None ,
343+ CassDataType :: Map {
344+ typ : MapDataType :: Key ( k) ,
345+ ..
346+ } if index == 0 => Some ( k) ,
347+ CassDataType :: Map {
348+ typ : MapDataType :: KeyAndValue ( k, v) ,
349+ ..
342350 } => match index {
343- 0 => key_type . as_ref ( ) ,
344- 1 => val_type . as_ref ( ) ,
351+ 0 => Some ( k ) ,
352+ 1 => Some ( v ) ,
345353 _ => None ,
346354 } ,
347355 CassDataType :: Tuple ( v) => v. get ( index) ,
@@ -359,17 +367,28 @@ impl CassDataType {
359367 }
360368 } ,
361369 CassDataType :: Map {
362- key_type, val_type, ..
370+ typ : MapDataType :: KeyAndValue ( _, _) ,
371+ ..
372+ } => Err ( CassError :: CASS_ERROR_LIB_BAD_PARAMS ) ,
373+ CassDataType :: Map {
374+ typ : MapDataType :: Key ( k) ,
375+ frozen,
363376 } => {
364- if key_type. is_some ( ) && val_type. is_some ( ) {
365- Err ( CassError :: CASS_ERROR_LIB_BAD_PARAMS )
366- } else if key_type. is_none ( ) {
367- * key_type = Some ( sub_type) ;
368- Ok ( ( ) )
369- } else {
370- * val_type = Some ( sub_type) ;
371- Ok ( ( ) )
372- }
377+ * self = CassDataType :: Map {
378+ typ : MapDataType :: KeyAndValue ( k. clone ( ) , sub_type) ,
379+ frozen : * frozen,
380+ } ;
381+ Ok ( ( ) )
382+ }
383+ CassDataType :: Map {
384+ typ : MapDataType :: Untyped ,
385+ frozen,
386+ } => {
387+ * self = CassDataType :: Map {
388+ typ : MapDataType :: Key ( sub_type) ,
389+ frozen : * frozen,
390+ } ;
391+ Ok ( ( ) )
373392 }
374393 CassDataType :: Tuple ( types) => {
375394 types. push ( sub_type) ;
@@ -421,8 +440,10 @@ pub fn get_column_type(column_type: &ColumnType) -> CassDataType {
421440 frozen : false ,
422441 } ,
423442 ColumnType :: Map ( key, value) => CassDataType :: Map {
424- key_type : Some ( Arc :: new ( get_column_type ( key. as_ref ( ) ) ) ) ,
425- val_type : Some ( Arc :: new ( get_column_type ( value. as_ref ( ) ) ) ) ,
443+ typ : MapDataType :: KeyAndValue (
444+ Arc :: new ( get_column_type ( key. as_ref ( ) ) ) ,
445+ Arc :: new ( get_column_type ( value. as_ref ( ) ) ) ,
446+ ) ,
426447 frozen : false ,
427448 } ,
428449 ColumnType :: Set ( boxed_type) => CassDataType :: Set {
@@ -473,8 +494,7 @@ pub unsafe extern "C" fn cass_data_type_new(value_type: CassValueType) -> *const
473494 } ,
474495 CassValueType :: CASS_VALUE_TYPE_TUPLE => CassDataType :: Tuple ( Vec :: new ( ) ) ,
475496 CassValueType :: CASS_VALUE_TYPE_MAP => CassDataType :: Map {
476- key_type : None ,
477- val_type : None ,
497+ typ : MapDataType :: Untyped ,
478498 frozen : false ,
479499 } ,
480500 CassValueType :: CASS_VALUE_TYPE_UDT => CassDataType :: UDT ( UDTDataType :: new ( ) ) ,
@@ -671,9 +691,11 @@ pub unsafe extern "C" fn cass_data_type_sub_type_count(data_type: *const CassDat
671691 CassDataType :: Value ( ..) => 0 ,
672692 CassDataType :: UDT ( udt_data_type) => udt_data_type. field_types . len ( ) as size_t ,
673693 CassDataType :: List { typ, .. } | CassDataType :: Set { typ, .. } => typ. is_some ( ) as size_t ,
674- CassDataType :: Map {
675- key_type, val_type, ..
676- } => key_type. is_some ( ) as size_t + val_type. is_some ( ) as size_t ,
694+ CassDataType :: Map { typ, .. } => match typ {
695+ MapDataType :: Untyped => 0 ,
696+ MapDataType :: Key ( _) => 1 ,
697+ MapDataType :: KeyAndValue ( _, _) => 2 ,
698+ } ,
677699 CassDataType :: Tuple ( v) => v. len ( ) as size_t ,
678700 CassDataType :: Custom ( ..) => 0 ,
679701 }
0 commit comments