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 heck::CamelCase;
|
||||||
use proc_macro2::{Ident, TokenStream};
|
use proc_macro2::{Ident, TokenStream};
|
||||||
use quote::{format_ident, quote, quote_spanned};
|
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");
|
ident.span() => compile_error!("you can only derive DeriveActiveModel on structs");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
.into_iter()
|
||||||
|
.filter(field_not_ignored);
|
||||||
|
|
||||||
let field: Vec<Ident> = fields
|
let field: Vec<Ident> = fields
|
||||||
.clone()
|
.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_value = None;
|
||||||
let mut default_expr = None;
|
let mut default_expr = None;
|
||||||
let mut indexed = false;
|
let mut indexed = false;
|
||||||
|
let mut ignore = false;
|
||||||
let mut unique = false;
|
let mut unique = false;
|
||||||
let mut sql_type = None;
|
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)]
|
// 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) => {
|
Meta::Path(p) => {
|
||||||
if let Some(name) = p.get_ident() {
|
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_keys.push(quote! { #field_name });
|
||||||
primary_key_types.push(field.ty.clone());
|
primary_key_types.push(field.ty.clone());
|
||||||
} else if name == "nullable" {
|
} 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 {
|
let field_type = match sql_type {
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
None => {
|
None => {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::attributes::derive_attr;
|
use crate::{attributes::derive_attr, util::field_not_ignored};
|
||||||
use heck::CamelCase;
|
use heck::CamelCase;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{format_ident, quote, quote_spanned};
|
use quote::{format_ident, quote, quote_spanned};
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
use syn::Ident;
|
||||||
|
|
||||||
enum Error {
|
enum Error {
|
||||||
InputNotStruct,
|
InputNotStruct,
|
||||||
@ -14,6 +15,7 @@ struct DeriveModel {
|
|||||||
entity_ident: syn::Ident,
|
entity_ident: syn::Ident,
|
||||||
field_idents: Vec<syn::Ident>,
|
field_idents: Vec<syn::Ident>,
|
||||||
ident: syn::Ident,
|
ident: syn::Ident,
|
||||||
|
ignore_attrs: Vec<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeriveModel {
|
impl DeriveModel {
|
||||||
@ -48,11 +50,17 @@ impl DeriveModel {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let ignore_attrs = fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| !field_not_ignored(field))
|
||||||
|
.collect();
|
||||||
|
|
||||||
Ok(DeriveModel {
|
Ok(DeriveModel {
|
||||||
column_idents,
|
column_idents,
|
||||||
entity_ident,
|
entity_ident,
|
||||||
field_idents,
|
field_idents,
|
||||||
ident,
|
ident,
|
||||||
|
ignore_attrs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,23 +78,56 @@ impl DeriveModel {
|
|||||||
let ident = &self.ident;
|
let ident = &self.ident;
|
||||||
let field_idents = &self.field_idents;
|
let field_idents = &self.field_idents;
|
||||||
let column_idents = &self.column_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!(
|
quote!(
|
||||||
impl sea_orm::FromQueryResult for #ident {
|
impl sea_orm::FromQueryResult for #ident {
|
||||||
fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result<Self, sea_orm::DbErr> {
|
fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result<Self, sea_orm::DbErr> {
|
||||||
Ok(Self {
|
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 ident = &self.ident;
|
||||||
let entity_ident = &self.entity_ident;
|
let entity_ident = &self.entity_ident;
|
||||||
let field_idents = &self.field_idents;
|
let ignore_attrs = &self.ignore_attrs;
|
||||||
let column_idents = &self.column_idents;
|
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);
|
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 attributes;
|
||||||
mod derives;
|
mod derives;
|
||||||
|
mod util;
|
||||||
|
|
||||||
#[proc_macro_derive(DeriveEntity, attributes(sea_orm))]
|
#[proc_macro_derive(DeriveEntity, attributes(sea_orm))]
|
||||||
pub fn derive_entity(input: TokenStream) -> TokenStream {
|
pub fn derive_entity(input: TokenStream) -> TokenStream {
|
||||||
@ -73,7 +74,7 @@ pub fn derive_model(input: TokenStream) -> TokenStream {
|
|||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(DeriveActiveModel)]
|
#[proc_macro_derive(DeriveActiveModel, attributes(sea_orm))]
|
||||||
pub fn derive_active_model(input: TokenStream) -> TokenStream {
|
pub fn derive_active_model(input: TokenStream) -> TokenStream {
|
||||||
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
|
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 cake_id: i32,
|
||||||
pub filling_id: i32,
|
pub filling_id: i32,
|
||||||
pub price: Decimal,
|
pub price: Decimal,
|
||||||
|
#[sea_orm(ignore)]
|
||||||
|
pub ignored_attr: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
@ -9,6 +9,8 @@ pub struct Entity;
|
|||||||
pub struct Model {
|
pub struct Model {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
#[sea_orm(ignore)]
|
||||||
|
pub ignored_attr: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If your column names are not in snake-case, derive `DeriveCustomColumn` here.
|
// If your column names are not in snake-case, derive `DeriveCustomColumn` here.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user