diff options
| author | Melody Horn <melody@boringcactus.com> | 2021-06-30 16:15:44 -0600 | 
|---|---|---|
| committer | Melody Horn <melody@boringcactus.com> | 2021-06-30 16:15:44 -0600 | 
| commit | a4f6e7af6576744e238ecafda826cbe602c23db5 (patch) | |
| tree | 652690507eb0cc634c6b9e913ccd86dbf0f57749 | |
| parent | b4c7c3cd480e626ac78b49ab91a95340ccfef26a (diff) | |
| download | tosin-a4f6e7af6576744e238ecafda826cbe602c23db5.tar.gz tosin-a4f6e7af6576744e238ecafda826cbe602c23db5.zip  | |
add getters & setters
not just making fields pub yet bc validation seems like a good idea
| -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  |