Merge pull request #166 from SeaQL/model-ignore-attribute
Model ignore attributes
This commit is contained in:
commit
5509048550
@ -1,3 +1,4 @@
|
||||
use crate::util::field_not_ignored;
|
||||
use heck::CamelCase;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
@ -14,7 +15,9 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
|
||||
ident.span() => compile_error!("you can only derive DeriveActiveModel on structs");
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
.into_iter()
|
||||
.filter(field_not_ignored);
|
||||
|
||||
let field: Vec<Ident> = fields
|
||||
.clone()
|
||||
|
@ -68,6 +68,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
||||
let mut default_value = None;
|
||||
let mut default_expr = None;
|
||||
let mut indexed = false;
|
||||
let mut ignore = false;
|
||||
let mut unique = false;
|
||||
let mut sql_type = None;
|
||||
// search for #[sea_orm(primary_key, auto_increment = false, column_type = "String(Some(255))", default_value = "new user", default_expr = "gen_random_uuid()", nullable, indexed, unique)]
|
||||
@ -120,7 +121,10 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
||||
}
|
||||
Meta::Path(p) => {
|
||||
if let Some(name) = p.get_ident() {
|
||||
if name == "primary_key" {
|
||||
if name == "ignore" {
|
||||
ignore = true;
|
||||
break;
|
||||
} else if name == "primary_key" {
|
||||
primary_keys.push(quote! { #field_name });
|
||||
primary_key_types.push(field.ty.clone());
|
||||
} else if name == "nullable" {
|
||||
@ -138,6 +142,11 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
||||
}
|
||||
}
|
||||
|
||||
if ignore {
|
||||
columns_enum.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
let field_type = match sql_type {
|
||||
Some(t) => t,
|
||||
None => {
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::attributes::derive_attr;
|
||||
use crate::{attributes::derive_attr, util::field_not_ignored};
|
||||
use heck::CamelCase;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use std::iter::FromIterator;
|
||||
use syn::Ident;
|
||||
|
||||
enum Error {
|
||||
InputNotStruct,
|
||||
@ -14,6 +15,7 @@ struct DeriveModel {
|
||||
entity_ident: syn::Ident,
|
||||
field_idents: Vec<syn::Ident>,
|
||||
ident: syn::Ident,
|
||||
ignore_attrs: Vec<bool>,
|
||||
}
|
||||
|
||||
impl DeriveModel {
|
||||
@ -48,11 +50,17 @@ impl DeriveModel {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let ignore_attrs = fields
|
||||
.iter()
|
||||
.map(|field| !field_not_ignored(field))
|
||||
.collect();
|
||||
|
||||
Ok(DeriveModel {
|
||||
column_idents,
|
||||
entity_ident,
|
||||
field_idents,
|
||||
ident,
|
||||
ignore_attrs,
|
||||
})
|
||||
}
|
||||
|
||||
@ -70,23 +78,56 @@ impl DeriveModel {
|
||||
let ident = &self.ident;
|
||||
let field_idents = &self.field_idents;
|
||||
let column_idents = &self.column_idents;
|
||||
let field_values: Vec<TokenStream> = column_idents
|
||||
.iter()
|
||||
.zip(&self.ignore_attrs)
|
||||
.map(|(column_ident, ignore)| {
|
||||
if *ignore {
|
||||
quote! {
|
||||
Default::default()
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
row.try_get(pre, sea_orm::IdenStatic::as_str(&<<Self as sea_orm::ModelTrait>::Entity as sea_orm::entity::EntityTrait>::Column::#column_ident).into())?
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
quote!(
|
||||
impl sea_orm::FromQueryResult for #ident {
|
||||
fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result<Self, sea_orm::DbErr> {
|
||||
Ok(Self {
|
||||
#(#field_idents: row.try_get(pre, sea_orm::IdenStatic::as_str(&<<Self as sea_orm::ModelTrait>::Entity as sea_orm::entity::EntityTrait>::Column::#column_idents).into())?),*
|
||||
#(#field_idents: #field_values),*
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fn impl_model_trait(&self) -> TokenStream {
|
||||
fn impl_model_trait<'a>(&'a self) -> TokenStream {
|
||||
let ident = &self.ident;
|
||||
let entity_ident = &self.entity_ident;
|
||||
let field_idents = &self.field_idents;
|
||||
let column_idents = &self.column_idents;
|
||||
let ignore_attrs = &self.ignore_attrs;
|
||||
let ignore = |(ident, ignore): (&'a Ident, &bool)| -> Option<&'a Ident> {
|
||||
if *ignore {
|
||||
None
|
||||
} else {
|
||||
Some(ident)
|
||||
}
|
||||
};
|
||||
let field_idents: Vec<&Ident> = self
|
||||
.field_idents
|
||||
.iter()
|
||||
.zip(ignore_attrs)
|
||||
.filter_map(ignore)
|
||||
.collect();
|
||||
let column_idents: Vec<&Ident> = self
|
||||
.column_idents
|
||||
.iter()
|
||||
.zip(ignore_attrs)
|
||||
.filter_map(ignore)
|
||||
.collect();
|
||||
|
||||
let missing_field_msg = format!("field does not exist on {}", ident);
|
||||
|
||||
|
@ -5,6 +5,7 @@ use syn::{parse_macro_input, DeriveInput, Error};
|
||||
|
||||
mod attributes;
|
||||
mod derives;
|
||||
mod util;
|
||||
|
||||
#[proc_macro_derive(DeriveEntity, attributes(sea_orm))]
|
||||
pub fn derive_entity(input: TokenStream) -> TokenStream {
|
||||
@ -73,7 +74,7 @@ pub fn derive_model(input: TokenStream) -> TokenStream {
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(DeriveActiveModel)]
|
||||
#[proc_macro_derive(DeriveActiveModel, attributes(sea_orm))]
|
||||
pub fn derive_active_model(input: TokenStream) -> TokenStream {
|
||||
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
|
||||
|
||||
|
26
sea-orm-macros/src/util.rs
Normal file
26
sea-orm-macros/src/util.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use syn::{punctuated::Punctuated, token::Comma, Field, Meta};
|
||||
|
||||
pub(crate) fn field_not_ignored(field: &Field) -> bool {
|
||||
for attr in field.attrs.iter() {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if ident != "sea_orm" {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated) {
|
||||
for meta in list.iter() {
|
||||
if let Meta::Path(path) = meta {
|
||||
if let Some(name) = path.get_ident() {
|
||||
if name == "ignore" {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
@ -19,6 +19,8 @@ pub struct Model {
|
||||
pub cake_id: i32,
|
||||
pub filling_id: i32,
|
||||
pub price: Decimal,
|
||||
#[sea_orm(ignore)]
|
||||
pub ignored_attr: i32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||
|
@ -9,6 +9,8 @@ pub struct Entity;
|
||||
pub struct Model {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
#[sea_orm(ignore)]
|
||||
pub ignored_attr: i32,
|
||||
}
|
||||
|
||||
// If your column names are not in snake-case, derive `DeriveCustomColumn` here.
|
||||
|
Loading…
x
Reference in New Issue
Block a user