clia-rustorm-codegen 0.18.0

code gen provides macro for generating code on data access objects on table metadata
Documentation
use crate::util::{
    find_attribute_value,
    find_crate_name,
};
use proc_macro2::TokenStream;
use syn::{
    Data,
    DeriveInput,
    Field,
    Ident,
    Lit,
    LitStr,
};

pub fn impl_from_dao(ast: &DeriveInput) -> TokenStream {
    let rustorm = find_crate_name();
    let name = &ast.ident;

    let fields = match ast.data {
        Data::Struct(ref data) => data.fields.iter().map(parse_field),
        Data::Enum(_) | Data::Union(_) => {
            panic!("#[derive(ToDao)] can only be used with structs")
        }
    };

    let get_fields = fields.map(|(column_name, field_name)| {
        quote! { #field_name: dao.get(#column_name).unwrap(),}
    });

    quote! {
        impl #rustorm::dao::FromDao for  #name {

            fn from_dao(dao: &#rustorm::Dao) -> Self {
                #name {
                    #(#get_fields)*
                }

            }
        }
    }
}

pub fn impl_to_dao(ast: &DeriveInput) -> TokenStream {
    let rustorm = find_crate_name();
    let name = &ast.ident;
    let generics = &ast.generics;

    let fields = match ast.data {
        Data::Struct(ref data) => data.fields.iter().map(parse_field),
        Data::Enum(_) | Data::Union(_) => {
            panic!("#[derive(ToDao)] can only be used with structs")
        }
    };

    let insert_fields = fields.map(|(column_name, field_name)| {
        quote! { dao.insert(#column_name, &self.#field_name);}
    });

    quote! {
        impl #generics #rustorm::dao::ToDao for #name #generics {
            fn to_dao(&self) -> #rustorm::Dao {
                let mut dao = #rustorm::Dao::new();
                #(#insert_fields)*
                dao
            }
        }

    }
}

fn parse_field(field: &Field) -> (Lit, &Ident) {
    let field_name = field.ident.as_ref().unwrap();
    let column_name = find_attribute_value(&field.attrs, "column_name")
        .unwrap_or_else(|| LitStr::new(&field_name.to_string(), field_name.span()))
        .into();

    (column_name, field_name)
}