@@ -5,6 +5,7 @@ use crate::serialize::value::{
55 SetOrListSerializationErrorKind , SetOrListTypeCheckErrorKind , TupleSerializationErrorKind ,
66 TupleTypeCheckErrorKind , UdtSerializationErrorKind , UdtTypeCheckErrorKind ,
77} ;
8+ use crate :: serialize:: writers:: WrittenCellProof ;
89use crate :: serialize:: { CellWriter , SerializationError } ;
910use crate :: value:: {
1011 Counter , CqlDate , CqlDuration , CqlTime , CqlTimestamp , CqlTimeuuid , CqlValue , CqlVarint ,
@@ -20,8 +21,31 @@ use std::str::FromStr;
2021use std:: sync:: Arc ;
2122
2223use assert_matches:: assert_matches;
24+ use thiserror:: Error ;
2325use uuid:: Uuid ;
2426
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+
2549#[ test]
2650fn test_dyn_serialize_value ( ) {
2751 let v: i32 = 123 ;
@@ -106,6 +130,70 @@ fn test_native_errors() {
106130 // a value which is at least 2GB in size.
107131}
108132
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+
109197#[ cfg( feature = "bigdecimal-04" ) ]
110198#[ test]
111199fn test_native_errors_bigdecimal_04 ( ) {
@@ -177,6 +265,25 @@ fn test_set_or_list_errors() {
177265 expected: & [ ColumnType :: Native ( NativeType :: Int ) ] ,
178266 }
179267 ) ;
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" ) ;
180287}
181288
182289#[ test]
@@ -248,6 +355,51 @@ fn test_map_errors() {
248355 expected: & [ ColumnType :: Native ( NativeType :: Int ) ] ,
249356 }
250357 ) ;
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" ) ;
251403}
252404
253405#[ test]
@@ -302,6 +454,25 @@ fn test_tuple_errors() {
302454 expected: & [ ColumnType :: Native ( NativeType :: Double ) ] ,
303455 }
304456 ) ;
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" ) ;
305476}
306477
307478#[ test]
0 commit comments