diff options
Diffstat (limited to 'tosin-macros')
-rw-r--r-- | tosin-macros/src/lib.rs | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/tosin-macros/src/lib.rs b/tosin-macros/src/lib.rs index 1019540..5773075 100644 --- a/tosin-macros/src/lib.rs +++ b/tosin-macros/src/lib.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; use std::fs; use proc_macro::TokenStream; -use quote::quote; +use quote::{format_ident, quote}; #[proc_macro_derive(Model, attributes(model))] pub fn model_derive(input: TokenStream) -> TokenStream { @@ -142,7 +142,7 @@ fn is_id(field: &syn::Field) -> bool { fn impl_model(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; - let lowercase_name = quote::format_ident!("{}", name.to_string().to_lowercase()); + let lowercase_name = format_ident!("{}", name.to_string().to_lowercase()); let ast_data = if let syn::Data::Struct(ast_data) = &ast.data { ast_data } else { @@ -204,6 +204,27 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream { } }) .collect(); + let (getters, setters): (Vec<_>, Vec<_>) = ast_data + .fields + .iter() + .map(|field| { + let ident = field.ident.as_ref().expect("anonymous field in model"); + let ty = &field.ty; + let getter = quote! { + pub fn #ident(&self) -> &#ty { + &self.#ident + } + }; + let set_ident = format_ident!("set_{}", ident); + // TODO only use impl Into<#ty> sometimes + let setter = quote! { + pub fn #set_ident(&mut self, #ident: impl Into<#ty>) { + self.#ident = #ident.into(); + } + }; + (getter, setter) + }) + .unzip(); let gen = quote! { impl #name { pub const META: ::tosin::db::models::ModelMeta = ::tosin::db::models::ModelMeta { @@ -239,6 +260,9 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream { todo!("update existing db item"); } } + + #(#getters)* + #(#setters)* } impl<__DB: tosin::db::diesel_backend::Backend, __ST> tosin::db::Queryable<__ST, __DB> for #name |