@@ -35,6 +35,7 @@ pub fn transcoder_decorator(ast: &syn::DeriveInput) -> TokenStream {
35
35
fn gen_decoder ( ctx : & Context , fields : & [ & Field ] ) -> TokenStream {
36
36
let struct_type = & ctx. ident_with_lifetime ;
37
37
let struct_name = ctx. ident ;
38
+ let struct_name_str = struct_name. to_string ( ) ;
38
39
39
40
// Make a decoder for each of the fields in the struct.
40
41
let field_defs: Vec < TokenStream > = fields
@@ -47,22 +48,10 @@ fn gen_decoder(ctx: &Context, fields: &[&Field]) -> TokenStream {
47
48
} else {
48
49
index. to_string ( )
49
50
} ;
50
- let error_message = format ! (
51
- "Could not decode field {} on {}" ,
52
- pos_in_struct,
53
- struct_name. to_string( )
54
- ) ;
55
-
56
- let decoder = quote ! {
57
- match :: rustler:: Decoder :: decode( terms[ #index] ) {
58
- Err ( _) => return Err ( :: rustler:: Error :: RaiseTerm ( Box :: new( #error_message) ) ) ,
59
- Ok ( value) => value
60
- }
61
- } ;
62
51
63
52
match ident {
64
- None => quote ! { #decoder } ,
65
- Some ( ident) => quote ! { #ident: #decoder } ,
53
+ None => quote ! { try_decode_index ( & terms , #pos_in_struct , #index ) ? } ,
54
+ Some ( ident) => quote ! { #ident: try_decode_index ( & terms , #pos_in_struct , #index ) ? } ,
66
55
}
67
56
} )
68
57
. collect ( ) ;
@@ -86,6 +75,17 @@ fn gen_decoder(ctx: &Context, fields: &[&Field]) -> TokenStream {
86
75
if terms. len( ) != #field_num {
87
76
return Err ( :: rustler:: Error :: BadArg ) ;
88
77
}
78
+
79
+ fn try_decode_index<' a, T >( terms: & [ :: rustler:: Term <' a>] , pos_in_struct: & str , index: usize ) -> Result <T , rustler:: Error >
80
+ where
81
+ T : rustler:: Decoder <' a>,
82
+ {
83
+ match :: rustler:: Decoder :: decode( terms[ index] ) {
84
+ Err ( _) => Err ( :: rustler:: Error :: RaiseTerm ( Box :: new(
85
+ format!( "Could not decode field {} on {}" , pos_in_struct, #struct_name_str) ) ) ) ,
86
+ Ok ( value) => Ok ( value)
87
+ }
88
+ }
89
89
Ok (
90
90
#construct
91
91
)
0 commit comments