@@ -6,33 +6,68 @@ use syn::{spanned::Spanned, DeriveInput};
66pub ( 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 ( ) )
42+ }
43+ crate :: parser:: StructFields :: Unnamed ( fields) => {
44+ let set_fields_code = fields. unnamed . iter ( ) . map ( |field| {
45+ let field_type = & field. ty ;
46+
47+ quote_spanned ! { field. span( ) =>
48+ {
49+ let ( col_ix, col_value) = vals_iter
50+ . next( )
51+ . unwrap( ) ; // vals_iter size is checked before this code is reached, so
52+ // it is safe to unwrap
53+
54+ <#field_type as FromCqlVal <:: std:: option:: Option <CqlValue >>>:: from_cql( col_value)
55+ . map_err( |e| FromRowError :: BadCqlVal {
56+ err: e,
57+ column: col_ix,
58+ } ) ?
59+ } ,
60+ }
61+ } ) ;
62+
63+ // This generates: ( {<field1_code>}, {<field2_code>}, ... )
64+ let fill_struct_code = quote ! {
65+ ( #( #set_fields_code) * )
66+ } ;
67+ ( fill_struct_code, fields. unnamed . len ( ) )
3268 }
33- } ) ;
69+ } ;
3470
35- let fields_count = struct_fields. named . len ( ) ;
3671 let generated = quote ! {
3772 impl #impl_generics #path:: FromRow for #struct_name #ty_generics #where_clause {
3873 fn from_row( row: #path:: Row )
@@ -49,9 +84,7 @@ pub(crate) fn from_row_derive(tokens_input: TokenStream) -> Result<TokenStream,
4984 }
5085 let mut vals_iter = row. columns. into_iter( ) . enumerate( ) ;
5186
52- Ok ( #struct_name {
53- #( #set_fields_code) *
54- } )
87+ Ok ( #struct_name #fill_struct_code)
5588 }
5689 }
5790 } ;
0 commit comments