aboutsummaryrefslogtreecommitdiff
path: root/tosin-macros
diff options
context:
space:
mode:
Diffstat (limited to 'tosin-macros')
-rw-r--r--tosin-macros/src/lib.rs39
1 files changed, 33 insertions, 6 deletions
diff --git a/tosin-macros/src/lib.rs b/tosin-macros/src/lib.rs
index 0da725e..60803ae 100644
--- a/tosin-macros/src/lib.rs
+++ b/tosin-macros/src/lib.rs
@@ -124,6 +124,15 @@ fn to_field_spec(field: &syn::Field) -> FieldInfo<impl quote::ToTokens> {
}
}
+fn is_id(field: &syn::Field) -> bool {
+ let name_matches = field
+ .ident
+ .as_ref()
+ .map_or(false, |name| name.to_string() == "id");
+ let type_matches = field.ty == syn::parse_str("Option<Id>").unwrap();
+ name_matches && type_matches
+}
+
fn impl_model(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let lowercase_name = quote::format_ident!("{}", name.to_string().to_lowercase());
@@ -136,18 +145,29 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream {
.fields
.iter()
.map(|field| {
- if field
- .ident
- .as_ref()
- .map_or(false, |name| name.to_string() == "id")
- && field.ty == syn::parse_str("Option<Id>").unwrap()
- {
+ if is_id(field) {
syn::parse_str("Id").unwrap()
} else {
field.ty.clone()
}
})
.collect();
+ let new_params: Vec<_> = ast_data
+ .fields
+ .iter()
+ .filter(|field| !is_id(field))
+ .map(|field| {
+ let ty = &field.ty;
+ let name = &field.ident;
+ quote! { #name: #ty }
+ })
+ .collect();
+ let field_names: Vec<_> = ast_data
+ .fields
+ .iter()
+ .filter(|field| !is_id(field))
+ .map(|field| &field.ident)
+ .collect();
let FieldsInfo {
tosin_fields,
diesel_columns,
@@ -159,6 +179,13 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream {
name: stringify!(#name),
fields: &[ #(#tosin_fields),* ],
};
+
+ pub fn new(#(#new_params),*) -> Self {
+ Self {
+ id: None,
+ #(#field_names),*
+ }
+ }
}
impl<__DB: tosin::db::diesel_backend::Backend, __ST> tosin::db::Queryable<__ST, __DB> for #name