@@ -5,6 +5,7 @@ use crate::serialize::value::{
5
5
SetOrListSerializationErrorKind , SetOrListTypeCheckErrorKind , TupleSerializationErrorKind ,
6
6
TupleTypeCheckErrorKind , UdtSerializationErrorKind , UdtTypeCheckErrorKind ,
7
7
} ;
8
+ use crate :: serialize:: writers:: WrittenCellProof ;
8
9
use crate :: serialize:: { CellWriter , SerializationError } ;
9
10
use crate :: value:: {
10
11
Counter , CqlDate , CqlDuration , CqlTime , CqlTimestamp , CqlTimeuuid , CqlValue , CqlVarint ,
@@ -20,8 +21,31 @@ use std::str::FromStr;
20
21
use std:: sync:: Arc ;
21
22
22
23
use assert_matches:: assert_matches;
24
+ use thiserror:: Error ;
23
25
use uuid:: Uuid ;
24
26
27
+ #[ derive( PartialEq , Eq , PartialOrd , Ord ) ]
28
+ struct SerializeWithCustomError ;
29
+
30
+ #[ derive( Error , Debug ) ]
31
+ #[ error( "Custom serialization error" ) ]
32
+ struct CustomSerializationError ;
33
+
34
+ impl SerializeValue for SerializeWithCustomError {
35
+ fn serialize < ' b > (
36
+ & self ,
37
+ _typ : & ColumnType ,
38
+ _writer : CellWriter < ' b > ,
39
+ ) -> Result < WrittenCellProof < ' b > , SerializationError > {
40
+ Err ( SerializationError :: new ( CustomSerializationError ) )
41
+ }
42
+ }
43
+
44
+ #[ cfg( feature = "secrecy-08" ) ]
45
+ impl secrecy_08:: Zeroize for SerializeWithCustomError {
46
+ fn zeroize ( & mut self ) { }
47
+ }
48
+
25
49
#[ test]
26
50
fn test_dyn_serialize_value ( ) {
27
51
let v: i32 = 123 ;
@@ -106,6 +130,70 @@ fn test_native_errors() {
106
130
// a value which is at least 2GB in size.
107
131
}
108
132
133
+ /// Helper function for tests of wrappers (Option<T>, Box<T> etc).
134
+ /// Its main purpose is to verify that the rust_name in typecheck error
135
+ /// is the name of whole container instead of container value (for example
136
+ /// `Option<i32>` instead of `i32`).
137
+ fn verify_typeck_error_in_wrapper < T : SerializeValue > ( v : T ) {
138
+ let err = do_serialize_err :: < T > ( v, & ColumnType :: Native ( NativeType :: Text ) ) ;
139
+ let err = get_typeck_err ( & err) ;
140
+ assert_eq ! ( err. rust_name, std:: any:: type_name:: <T >( ) ) ;
141
+ assert_eq ! ( err. got, ColumnType :: Native ( NativeType :: Text ) ) ;
142
+ assert_matches ! (
143
+ err. kind,
144
+ BuiltinTypeCheckErrorKind :: MismatchedType {
145
+ expected: & [ ColumnType :: Native ( NativeType :: Int ) ]
146
+ }
147
+ ) ;
148
+ }
149
+
150
+ fn verify_custom_error_in_wrapper < T : SerializeValue > ( v : T ) {
151
+ let err = do_serialize_err :: < T > ( v, & ColumnType :: Native ( NativeType :: BigInt ) ) ;
152
+ err. 0
153
+ . downcast_ref :: < CustomSerializationError > ( )
154
+ . expect ( "CustomSerializationError" ) ;
155
+ }
156
+
157
+ #[ cfg( feature = "secrecy-08" ) ]
158
+ #[ test]
159
+ fn test_secrecy_08_errors ( ) {
160
+ use secrecy_08:: Secret ;
161
+ verify_typeck_error_in_wrapper :: < Secret < i32 > > ( Secret :: new ( 123 ) ) ;
162
+ verify_custom_error_in_wrapper :: < Secret < SerializeWithCustomError > > ( Secret :: new (
163
+ SerializeWithCustomError ,
164
+ ) ) ;
165
+ }
166
+
167
+ #[ test]
168
+ fn test_option_errors ( ) {
169
+ verify_typeck_error_in_wrapper :: < Option < i32 > > ( Some ( 123 ) ) ;
170
+ verify_custom_error_in_wrapper :: < Option < SerializeWithCustomError > > ( Some (
171
+ SerializeWithCustomError ,
172
+ ) ) ;
173
+ }
174
+
175
+ #[ test]
176
+ fn test_maybe_unset_errors ( ) {
177
+ verify_typeck_error_in_wrapper :: < MaybeUnset < i32 > > ( MaybeUnset :: Set ( 123 ) ) ;
178
+ verify_custom_error_in_wrapper :: < MaybeUnset < SerializeWithCustomError > > ( MaybeUnset :: Set (
179
+ SerializeWithCustomError ,
180
+ ) ) ;
181
+ }
182
+
183
+ #[ test]
184
+ fn test_ref_errors ( ) {
185
+ verify_typeck_error_in_wrapper :: < & i32 > ( & 123_i32 ) ;
186
+ verify_custom_error_in_wrapper :: < & SerializeWithCustomError > ( & SerializeWithCustomError ) ;
187
+ }
188
+
189
+ #[ test]
190
+ fn test_box_errors ( ) {
191
+ verify_typeck_error_in_wrapper :: < Box < i32 > > ( Box :: new ( 123 ) ) ;
192
+ verify_custom_error_in_wrapper :: < Box < SerializeWithCustomError > > ( Box :: new (
193
+ SerializeWithCustomError ,
194
+ ) ) ;
195
+ }
196
+
109
197
#[ cfg( feature = "bigdecimal-04" ) ]
110
198
#[ test]
111
199
fn test_native_errors_bigdecimal_04 ( ) {
@@ -177,6 +265,25 @@ fn test_set_or_list_errors() {
177
265
expected: & [ ColumnType :: Native ( NativeType :: Int ) ] ,
178
266
}
179
267
) ;
268
+
269
+ // Test serialization with custom error
270
+ let err = do_serialize_err (
271
+ vec ! [ SerializeWithCustomError ] ,
272
+ & ColumnType :: Collection {
273
+ frozen : false ,
274
+ typ : CollectionType :: Set ( Box :: new ( ColumnType :: Native ( NativeType :: Double ) ) ) ,
275
+ } ,
276
+ ) ;
277
+ let err = get_ser_err ( & err) ;
278
+ let BuiltinSerializationErrorKind :: SetOrListError (
279
+ SetOrListSerializationErrorKind :: ElementSerializationFailed ( err) ,
280
+ ) = & err. kind
281
+ else {
282
+ panic ! ( "unexpected error kind: {}" , err. kind)
283
+ } ;
284
+ err. 0
285
+ . downcast_ref :: < CustomSerializationError > ( )
286
+ . expect ( "CustomSerializationError" ) ;
180
287
}
181
288
182
289
#[ test]
@@ -248,6 +355,51 @@ fn test_map_errors() {
248
355
expected: & [ ColumnType :: Native ( NativeType :: Int ) ] ,
249
356
}
250
357
) ;
358
+
359
+ // Test serialization with custom error
360
+ // Value
361
+ let err = do_serialize_err (
362
+ BTreeMap :: from ( [ ( 123_i32 , SerializeWithCustomError ) ] ) ,
363
+ & ColumnType :: Collection {
364
+ frozen : false ,
365
+ typ : CollectionType :: Map (
366
+ Box :: new ( ColumnType :: Native ( NativeType :: Int ) ) ,
367
+ Box :: new ( ColumnType :: Native ( NativeType :: Int ) ) ,
368
+ ) ,
369
+ } ,
370
+ ) ;
371
+ let err = get_ser_err ( & err) ;
372
+ let BuiltinSerializationErrorKind :: MapError (
373
+ MapSerializationErrorKind :: ValueSerializationFailed ( err) ,
374
+ ) = & err. kind
375
+ else {
376
+ panic ! ( "unexpected error kind: {}" , err. kind)
377
+ } ;
378
+ err. 0
379
+ . downcast_ref :: < CustomSerializationError > ( )
380
+ . expect ( "CustomSerializationError" ) ;
381
+
382
+ // Key
383
+ let err = do_serialize_err (
384
+ BTreeMap :: from ( [ ( SerializeWithCustomError , 123_i32 ) ] ) ,
385
+ & ColumnType :: Collection {
386
+ frozen : false ,
387
+ typ : CollectionType :: Map (
388
+ Box :: new ( ColumnType :: Native ( NativeType :: Int ) ) ,
389
+ Box :: new ( ColumnType :: Native ( NativeType :: Int ) ) ,
390
+ ) ,
391
+ } ,
392
+ ) ;
393
+ let err = get_ser_err ( & err) ;
394
+ let BuiltinSerializationErrorKind :: MapError ( MapSerializationErrorKind :: KeySerializationFailed (
395
+ err,
396
+ ) ) = & err. kind
397
+ else {
398
+ panic ! ( "unexpected error kind: {}" , err. kind)
399
+ } ;
400
+ err. 0
401
+ . downcast_ref :: < CustomSerializationError > ( )
402
+ . expect ( "CustomSerializationError" ) ;
251
403
}
252
404
253
405
#[ test]
@@ -302,6 +454,25 @@ fn test_tuple_errors() {
302
454
expected: & [ ColumnType :: Native ( NativeType :: Double ) ] ,
303
455
}
304
456
) ;
457
+
458
+ // Test serialization with custom error
459
+ let err = do_serialize_err (
460
+ ( SerializeWithCustomError , SerializeWithCustomError ) ,
461
+ & ColumnType :: Tuple ( vec ! [
462
+ ColumnType :: Native ( NativeType :: Double ) ,
463
+ ColumnType :: Native ( NativeType :: Double ) ,
464
+ ] ) ,
465
+ ) ;
466
+ let err = get_ser_err ( & err) ;
467
+ let BuiltinSerializationErrorKind :: TupleError (
468
+ TupleSerializationErrorKind :: ElementSerializationFailed { index : 0 , err } ,
469
+ ) = & err. kind
470
+ else {
471
+ panic ! ( "unexpected error kind: {}" , err. kind)
472
+ } ;
473
+ err. 0
474
+ . downcast_ref :: < CustomSerializationError > ( )
475
+ . expect ( "CustomSerializationError" ) ;
305
476
}
306
477
307
478
#[ test]
0 commit comments