use proc_macro2::TokenStream;
use quote::quote;
use syn::{ItemStruct, Path};
pub fn to_row(input: &ItemStruct, import_location: &Path) -> syn::Result<TokenStream> {
if !input.generics.params.is_empty() {
return Err(syn::Error::new_spanned(
&input.generics,
"ToRow cannot be derived for structs with generic parameters (types, lifetimes, or consts)",
));
}
let struct_name = &input.ident;
if input.fields.is_empty() {
let expanded = quote! {
impl #import_location::format::ToRow for #struct_name {
fn to_row(&self) -> #import_location::PyroRow<'_> {
#import_location::PyroRow::new()
}
}
};
return Ok(TokenStream::from(expanded));
}
let mut field_conversions = Vec::with_capacity(input.fields.len());
for f in &input.fields {
let name = f.ident.as_ref().ok_or_else(|| {
syn::Error::new_spanned(f, "ToRow can only be derived for structs with named fields")
})?;
let name_str = name.to_string();
field_conversions.push(quote! {
(#name_str, #import_location::PyroValue::from(&self.#name))
});
}
let expanded = quote! {
impl #import_location::format::ToRow for #struct_name {
fn to_row(&self) -> #import_location::PyroRow<'_> {
#import_location::PyroRow::from([
#(#field_conversions),*
])
}
}
};
Ok(TokenStream::from(expanded))
}