common_macro/row/
into_row.rs1use proc_macro2::TokenStream as TokenStream2;
16use quote::quote;
17use syn::spanned::Spanned;
18use syn::{DeriveInput, Result};
19
20use crate::row::utils::{
21 ParsedField, convert_column_data_type_to_value_data_ident, extract_struct_fields,
22 get_column_data_type, parse_fields_from_fields_named,
23};
24use crate::row::{META_KEY_COL, META_KEY_DATATYPE};
25
26pub(crate) fn derive_into_row_impl(input: DeriveInput) -> Result<TokenStream2> {
27 let Some(fields) = extract_struct_fields(&input.data) else {
28 return Err(syn::Error::new(
29 input.span(),
30 "IntoRow can only be derived for structs",
31 ));
32 };
33 let ident = input.ident;
34 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
35 let fields = parse_fields_from_fields_named(fields)?;
36
37 let impl_to_row_method = impl_into_row_method_combined(&fields)?;
39 Ok(quote! {
40 impl #impl_generics #ident #ty_generics #where_clause {
41 #impl_to_row_method
42 }
43 })
44}
45
46fn impl_into_row_method_combined(fields: &[ParsedField<'_>]) -> Result<TokenStream2> {
47 let value_exprs = fields
48 .iter()
49 .map(|field| {
50 let ParsedField {ident, field_type, column_data_type, column_attribute} = field;
51 let Some(column_data_type) = get_column_data_type(column_data_type, column_attribute)
52 else {
53 return Err(syn::Error::new(
54 ident.span(),
55 format!(
56 "expected to set data type explicitly via [({META_KEY_COL}({META_KEY_DATATYPE} = \"...\"))]"
57 ),
58 ));
59 };
60 let value_data = convert_column_data_type_to_value_data_ident(&column_data_type.data_type);
61 let expr = if field_type.is_optional() {
62 quote! {
63 match self.#ident {
64 Some(v) => Value {
65 value_data: Some(ValueData::#value_data(v.into())),
66 },
67 None => Value { value_data: None },
68 }
69 }
70 } else {
71 quote! {
72 Value {
73 value_data: Some(ValueData::#value_data(self.#ident.into())),
74 }
75 }
76 };
77 Ok(expr)
78 })
79 .collect::<Result<Vec<_>>>()?;
80
81 Ok(quote! {
82 pub fn into_row(self) -> Row {
83 Row {
84 values: vec![ #( #value_exprs ),* ]
85 }
86 }
87 })
88}