From 00dff6960d0e89ef9f0aba4185ba98841115fc66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=A4=E3=83=BC=E3=83=8E=E3=82=B7=E3=83=A5?= Date: Tue, 19 Mar 2024 14:30:09 +0900 Subject: [PATCH 1/3] feat: implement `skip` for DerivePartialModel (as for FromQueryResult) --- sea-orm-macros/src/derives/partial_model.rs | 50 ++++++++++++--------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/sea-orm-macros/src/derives/partial_model.rs b/sea-orm-macros/src/derives/partial_model.rs index 0413fc86b..53f7ac173 100644 --- a/sea-orm-macros/src/derives/partial_model.rs +++ b/sea-orm-macros/src/derives/partial_model.rs @@ -16,11 +16,12 @@ use self::util::GetAsKVMeta; #[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,35 +96,39 @@ impl DerivePartialModel { .get_as_kv("from_expr") .map(|s| syn::parse_str::(&s).map_err(Error::Syn)) .transpose()?; + skip = meta.get_as_kv("skip").is_some(); } } } let field_name = field.ident.unwrap(); - let col_as = match (from_col, from_expr) { - (None, None) => { + let col_as = match (from_col, from_expr, skip) { + (Some(col), None, false) => { if entity.is_none() { - return Err(Error::EntityNotSpecific); + return Err(Error::EntityNotSpecified); } - ColumnAs::Col(format_ident!( - "{}", - field_name.to_string().to_upper_camel_case() - )) + + let field = field_name.to_string(); + ColumnAs::ColAlias { col, field } } - (None, Some(expr)) => ColumnAs::Expr { + (None, Some(expr), false) => ColumnAs::Expr { expr, field_name: field_name.to_string(), }, - (Some(col), None) => { + (None, None, true) => { + continue; + } + (None, None, false) => { if entity.is_none() { - return Err(Error::EntityNotSpecific); + return Err(Error::EntityNotSpecified); } - - let field = field_name.to_string(); - ColumnAs::ColAlias { col, field } + ColumnAs::Col(format_ident!( + "{}", + field_name.to_string().to_upper_camel_case() + )) } - (Some(_), Some(_)) => return Err(Error::BothFromColAndFromExpr(field_span)), + _ => return Err(Error::MultipleSourcesSpecified(field_span)), }; column_as_list.push(col_as); } @@ -179,16 +185,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), } From 03c113001711a91f9802d5659973190cdd225f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=A4=E3=83=BC=E3=83=8E=E3=82=B7=E3=83=A5?= Date: Tue, 19 Mar 2024 14:30:43 +0900 Subject: [PATCH 2/3] feat: add test for skipping column in DerivePartialModel --- tests/partial_model_tests.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/partial_model_tests.rs b/tests/partial_model_tests.rs index 10407c22e..999afa314 100644 --- a/tests/partial_model_tests.rs +++ b/tests/partial_model_tests.rs @@ -54,3 +54,11 @@ struct FieldFromExpr { #[sea_orm(from_expr = "Expr::col(Column::Id).equals(Column::Foo)")] _bar: bool, } + +#[derive(FromQueryResult, DerivePartialModel)] +struct SkipField { + #[sea_orm(from_col = "foo2")] + _foo: i32, + #[sea_orm(skip)] + _test_does_not_exist: Option<()>, +} From 64127fb4d05454ee75b63c7acd2e36aad099c93a Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Thu, 2 May 2024 21:32:34 +0800 Subject: [PATCH 3/3] WIP --- sea-orm-macros/src/derives/partial_model.rs | 48 +++++++++++++-------- tests/partial_model_tests.rs | 3 +- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/sea-orm-macros/src/derives/partial_model.rs b/sea-orm-macros/src/derives/partial_model.rs index 53f7ac173..6081ae73d 100644 --- a/sea-orm-macros/src/derives/partial_model.rs +++ b/sea-orm-macros/src/derives/partial_model.rs @@ -11,7 +11,7 @@ use syn::Expr; use syn::Meta; -use self::util::GetAsKVMeta; +use self::util::{GetAsKVMeta, GetMeta}; #[derive(Debug)] enum Error { @@ -96,39 +96,40 @@ impl DerivePartialModel { .get_as_kv("from_expr") .map(|s| syn::parse_str::(&s).map_err(Error::Syn)) .transpose()?; - skip = meta.get_as_kv("skip").is_some(); + skip = meta.exists("skip"); } } } + if skip { + continue; + } + let field_name = field.ident.unwrap(); - let col_as = match (from_col, from_expr, skip) { - (Some(col), None, false) => { + let col_as = match (from_col, from_expr) { + (None, None) => { if entity.is_none() { return Err(Error::EntityNotSpecified); } - - let field = field_name.to_string(); - ColumnAs::ColAlias { col, field } + ColumnAs::Col(format_ident!( + "{}", + field_name.to_string().to_upper_camel_case() + )) } - (None, Some(expr), false) => ColumnAs::Expr { + (None, Some(expr)) => ColumnAs::Expr { expr, field_name: field_name.to_string(), }, - (None, None, true) => { - continue; - } - (None, None, false) => { + (Some(col), None) => { if entity.is_none() { return Err(Error::EntityNotSpecified); } - ColumnAs::Col(format_ident!( - "{}", - field_name.to_string().to_upper_camel_case() - )) + + let field = field_name.to_string(); + ColumnAs::ColAlias { col, field } } - _ => return Err(Error::MultipleSourcesSpecified(field_span)), + (Some(_), Some(_)) => return Err(Error::MultipleSourcesSpecified(field_span)), }; column_as_list.push(col_as); } @@ -229,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 999afa314..abbdb110e 100644 --- a/tests/partial_model_tests.rs +++ b/tests/partial_model_tests.rs @@ -56,9 +56,10 @@ struct FieldFromExpr { } #[derive(FromQueryResult, DerivePartialModel)] +#[sea_orm(entity = "Entity")] struct SkipField { #[sea_orm(from_col = "foo2")] _foo: i32, #[sea_orm(skip)] - _test_does_not_exist: Option<()>, + _bar: Option<()>, }