123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- use proc_macro::TokenStream;
- use syn::{parse_macro_input, DeriveInput};
- use quote::{quote,format_ident};
- use convert_case::{Case, Casing};
- #[proc_macro_derive(Entity, attributes(microrm))]
- pub fn derive_model(tokens: TokenStream) -> TokenStream {
- let input = parse_macro_input!(tokens as DeriveInput);
- let struct_name = &input.ident;
- let enum_name = format_ident!("{}Columns", &input.ident);
- let table_name = format!("{}", struct_name).to_case(Case::Snake);
- if let syn::Data::Struct(st) = input.data {
- if let syn::Fields::Named(fields) = st.fields {
- let mut variants = syn::punctuated::Punctuated::<syn::Ident, syn::token::Comma>::new();
- let mut field_names = syn::punctuated::Punctuated::<proc_macro2::TokenStream, syn::token::Comma>::new();
- let mut value_references = syn::punctuated::Punctuated::<proc_macro2::TokenStream, syn::token::Comma>::new();
- for name in fields.named.iter() {
- let converted_case = format!("{}", name.ident.as_ref().unwrap().clone()).to_case(Case::UpperCamel);
- let converted_case = format_ident!("{}", converted_case);
- variants.push(converted_case.clone());
- let field_name = name.ident.as_ref().unwrap().clone();
- let field_name_str = format!("{}", field_name);
- field_names.push(quote!{ Self::Column::#converted_case => #field_name_str }.into());
- value_references.push(quote!{ &self. #field_name });
- }
- let ret = quote!{
- #[derive(Clone,Copy,strum::IntoStaticStr,strum::EnumCount)]
- enum #enum_name {
- #variants
- }
- impl crate::model::Entity for #struct_name {
- fn table_name() -> &'static str { #table_name }
- type Column = #enum_name;
- fn column_count() -> usize {
- <Self::Column as strum::EnumCount>::COUNT
- }
- fn index(c: Self::Column) -> usize {
- c as usize
- }
- fn name(c: Self::Column) -> &'static str {
- match c {
- #field_names
- }
- }
- fn values(&self) -> Vec<&dyn rusqlite::ToSql> {
- vec![ #value_references ]
- }
- }
- }.into();
- ret
- }
- else { panic!("Can only use derive(Model) on non-unit structs with named fields!") }
- }
- else { panic!("Can only use derive(Model) on structs!") }
- }
|