Skip to content

Commit edce65e

Browse files
committed
Speed-up compilation of NifTuple and NifRecord
1 parent f58df32 commit edce65e

File tree

2 files changed

+29
-27
lines changed

2 files changed

+29
-27
lines changed

rustler_codegen/src/record.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,13 @@ fn gen_decoder(ctx: &Context, fields: &[&Field], atoms_module_name: &Ident) -> T
6262
} else {
6363
index.to_string()
6464
};
65-
let error_message = format!(
66-
"Could not decode field {} on Record {}",
67-
pos_in_struct,
68-
struct_name.to_string()
69-
);
7065
let actual_index = index + 1;
71-
let decoder = quote! {
72-
match ::rustler::Decoder::decode(terms[#actual_index]) {
73-
Err(_) => return Err(::rustler::Error::RaiseTerm(Box::new(#error_message))),
74-
Ok(value) => value
75-
}
76-
};
7766

7867
match ident {
79-
None => quote! { #decoder },
80-
Some(ident) => quote! { #ident: #decoder },
68+
None => quote! { try_decode_index(&terms, #pos_in_struct, #actual_index)? },
69+
Some(ident) => {
70+
quote! { #ident: try_decode_index(&terms, #pos_in_struct, #actual_index)? }
71+
}
8172
}
8273
})
8374
.collect();
@@ -116,6 +107,17 @@ fn gen_decoder(ctx: &Context, fields: &[&Field], atoms_module_name: &Ident) -> T
116107
return Err(::rustler::Error::Atom("invalid_record"));
117108
}
118109

110+
fn try_decode_index<'a, T>(terms: &[::rustler::Term<'a>], pos_in_struct: &str, index: usize) -> Result<T, rustler::Error>
111+
where
112+
T: rustler::Decoder<'a>,
113+
{
114+
match ::rustler::Decoder::decode(terms[index]) {
115+
Err(_) => Err(::rustler::Error::RaiseTerm(Box::new(
116+
format!("Could not decode field {} on Record {}", pos_in_struct, #struct_name_str)))),
117+
Ok(value) => Ok(value)
118+
}
119+
}
120+
119121
Ok(
120122
#construct
121123
)

rustler_codegen/src/tuple.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub fn transcoder_decorator(ast: &syn::DeriveInput) -> TokenStream {
3535
fn gen_decoder(ctx: &Context, fields: &[&Field]) -> TokenStream {
3636
let struct_type = &ctx.ident_with_lifetime;
3737
let struct_name = ctx.ident;
38+
let struct_name_str = struct_name.to_string();
3839

3940
// Make a decoder for each of the fields in the struct.
4041
let field_defs: Vec<TokenStream> = fields
@@ -47,22 +48,10 @@ fn gen_decoder(ctx: &Context, fields: &[&Field]) -> TokenStream {
4748
} else {
4849
index.to_string()
4950
};
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-
};
6251

6352
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)? },
6655
}
6756
})
6857
.collect();
@@ -86,6 +75,17 @@ fn gen_decoder(ctx: &Context, fields: &[&Field]) -> TokenStream {
8675
if terms.len() != #field_num {
8776
return Err(::rustler::Error::BadArg);
8877
}
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+
}
8989
Ok(
9090
#construct
9191
)

0 commit comments

Comments
 (0)