aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tosin-macros/src/lib.rs28
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