diff --git a/sea-orm-macros/src/derives/partial_model.rs b/sea-orm-macros/src/derives/partial_model.rs index 0413fc86b..6081ae73d 100644 --- a/sea-orm-macros/src/derives/partial_model.rs +++ b/sea-orm-macros/src/derives/partial_model.rs @@ -11,16 +11,17 @@ use syn::Expr; use syn::Meta; -use self::util::GetAsKVMeta; +use self::util::{GetAsKVMeta, GetMeta}; #[derive(Debug)] enum Error { InputNotStruct, - EntityNotSpecific, + EntityNotSpecified, NotSupportGeneric(Span), - BothFromColAndFromExpr(Span), + MultipleSourcesSpecified(Span), Syn(syn::Error), } + #[derive(Debug, PartialEq, Eq)] enum ColumnAs { /// column in the model @@ -78,6 +79,7 @@ impl DerivePartialModel { let mut from_col = None; let mut from_expr = None; + let mut skip = false; for attr in field.attrs.iter() { if !attr.path().is_ident("sea_orm") { @@ -94,16 +96,21 @@ impl DerivePartialModel { .get_as_kv("from_expr") .map(|s| syn::parse_str::(&s).map_err(Error::Syn)) .transpose()?; + skip = meta.exists("skip"); } } } + if skip { + continue; + } + let field_name = field.ident.unwrap(); let col_as = match (from_col, from_expr) { (None, None) => { if entity.is_none() { - return Err(Error::EntityNotSpecific); + return Err(Error::EntityNotSpecified); } ColumnAs::Col(format_ident!( "{}", @@ -116,13 +123,13 @@ impl DerivePartialModel { }, (Some(col), None) => { if entity.is_none() { - return Err(Error::EntityNotSpecific); + return Err(Error::EntityNotSpecified); } let field = field_name.to_string(); ColumnAs::ColAlias { col, field } } - (Some(_), Some(_)) => return Err(Error::BothFromColAndFromExpr(field_span)), + (Some(_), Some(_)) => return Err(Error::MultipleSourcesSpecified(field_span)), }; column_as_list.push(col_as); } @@ -179,16 +186,16 @@ pub fn expand_derive_partial_model(input: syn::DeriveInput) -> syn::Result partial_model.expand(), Err(Error::NotSupportGeneric(span)) => Ok(quote_spanned! { - span => compile_error!("you can only derive `DerivePartialModel` on named struct"); + span => compile_error!("you can only derive `DerivePartialModel` on named, non-generic structs"); }), - Err(Error::BothFromColAndFromExpr(span)) => Ok(quote_spanned! { - span => compile_error!("you can only use one of `from_col` or `from_expr`"); + Err(Error::MultipleSourcesSpecified(span)) => Ok(quote_spanned! { + span => compile_error!("you can only use one of `from_col`, `from_expr` or `skip`"); }), - Err(Error::EntityNotSpecific) => Ok(quote_spanned! { - ident_span => compile_error!("you need specific which entity you are using") + Err(Error::EntityNotSpecified) => Ok(quote_spanned! { + ident_span => compile_error!("you need to specify which entity you are using") }), Err(Error::InputNotStruct) => Ok(quote_spanned! { - ident_span => compile_error!("you can only derive `DerivePartialModel` on named struct"); + ident_span => compile_error!("you can only derive `DerivePartialModel` on named structs"); }), Err(Error::Syn(err)) => Err(err), } @@ -223,6 +230,19 @@ mod util { } } } + + pub(super) trait GetMeta { + fn exists(&self, k: &str) -> bool; + } + + impl GetMeta for Meta { + fn exists(&self, k: &str) -> bool { + let Meta::Path(path) = self else { + return false; + }; + path.is_ident(k) + } + } } #[cfg(test)] diff --git a/tests/partial_model_tests.rs b/tests/partial_model_tests.rs index 10407c22e..abbdb110e 100644 --- a/tests/partial_model_tests.rs +++ b/tests/partial_model_tests.rs @@ -54,3 +54,12 @@ struct FieldFromExpr { #[sea_orm(from_expr = "Expr::col(Column::Id).equals(Column::Foo)")] _bar: bool, } + +#[derive(FromQueryResult, DerivePartialModel)] +#[sea_orm(entity = "Entity")] +struct SkipField { + #[sea_orm(from_col = "foo2")] + _foo: i32, + #[sea_orm(skip)] + _bar: Option<()>, +}