Skip to content

Commit d34d9f1

Browse files
committed
from_row: adjust code for named fields
This commit prepares for code generation for unnamed fields. The behaviour for named fields becomes unchanged, however code generation logic was slightly adjusted so the very similar approach can be applied to unnamed fields.
1 parent b77bf05 commit d34d9f1

File tree

1 file changed

+32
-24
lines changed

1 file changed

+32
-24
lines changed

scylla-macros/src/from_row.rs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,43 @@ use syn::{spanned::Spanned, DeriveInput};
66
pub(crate) fn from_row_derive(tokens_input: TokenStream) -> Result<TokenStream, syn::Error> {
77
let item = syn::parse::<DeriveInput>(tokens_input)?;
88
let path = crate::parser::get_path(&item)?;
9-
let struct_fields = crate::parser::parse_named_fields(&item, "FromRow")?;
9+
let struct_fields = crate::parser::parse_struct_fields(&item, "FromRow")?;
1010

1111
let struct_name = &item.ident;
1212
let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl();
1313

14-
// Generates tokens for field_name: field_type::from_cql(vals_iter.next().ok_or(...)?), ...
15-
let set_fields_code = struct_fields.named.iter().map(|field| {
16-
let field_name = &field.ident;
17-
let field_type = &field.ty;
18-
19-
quote_spanned! {field.span() =>
20-
#field_name: {
21-
let (col_ix, col_value) = vals_iter
22-
.next()
23-
.unwrap(); // vals_iter size is checked before this code is reached, so
24-
// it is safe to unwrap
25-
26-
<#field_type as FromCqlVal<::std::option::Option<CqlValue>>>::from_cql(col_value)
27-
.map_err(|e| FromRowError::BadCqlVal {
28-
err: e,
29-
column: col_ix,
30-
})?
31-
},
14+
// Generates a token that sets the values of struct fields: field_type::from_cql(...)
15+
let (fill_struct_code, fields_count) = match struct_fields {
16+
crate::parser::StructFields::Named(fields) => {
17+
let set_fields_code = fields.named.iter().map(|field| {
18+
let field_name = &field.ident;
19+
let field_type = &field.ty;
20+
21+
quote_spanned! {field.span() =>
22+
#field_name: {
23+
let (col_ix, col_value) = vals_iter
24+
.next()
25+
.unwrap(); // vals_iter size is checked before this code is reached, so
26+
// it is safe to unwrap
27+
28+
<#field_type as FromCqlVal<::std::option::Option<CqlValue>>>::from_cql(col_value)
29+
.map_err(|e| FromRowError::BadCqlVal {
30+
err: e,
31+
column: col_ix,
32+
})?
33+
},
34+
}
35+
});
36+
37+
// This generates: { field1: {field1_code}, field2: {field2_code}, ...}
38+
let fill_struct_code = quote! {
39+
{#(#set_fields_code)*}
40+
};
41+
(fill_struct_code, fields.named.len())
3242
}
33-
});
43+
crate::parser::StructFields::Unnamed(_fields) => todo!(),
44+
};
3445

35-
let fields_count = struct_fields.named.len();
3646
let generated = quote! {
3747
impl #impl_generics #path::FromRow for #struct_name #ty_generics #where_clause {
3848
fn from_row(row: #path::Row)
@@ -49,9 +59,7 @@ pub(crate) fn from_row_derive(tokens_input: TokenStream) -> Result<TokenStream,
4959
}
5060
let mut vals_iter = row.columns.into_iter().enumerate();
5161

52-
Ok(#struct_name {
53-
#(#set_fields_code)*
54-
})
62+
Ok(#struct_name #fill_struct_code)
5563
}
5664
}
5765
};

0 commit comments

Comments
 (0)