Skip to content

Commit

Permalink
Merge branch 'master' into fix-conflex
Browse files Browse the repository at this point in the history
  • Loading branch information
Goodjooy authored Mar 19, 2024
2 parents a321f0a + 4d8f559 commit a43d781
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 8 deletions.
27 changes: 22 additions & 5 deletions sea-orm-macros/src/derives/partial_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ use syn::Meta;

use self::util::GetAsKVMeta;

use super::util::field_attr_contain_key;

#[derive(Debug)]
enum Error {
InputNotStruct,
EntityNotSpecific,
NotSupportGeneric(Span),
BothFromColAndFromExpr(Span),
FlattenNotOnly(Span),
Syn(syn::Error),
}
#[derive(Debug, PartialEq, Eq)]
Expand All @@ -29,6 +32,8 @@ enum ColumnAs {
ColAlias { col: syn::Ident, field: String },
/// from an expr
Expr { expr: syn::Expr, field_name: String },
/// flatten
Flatten { ty: syn::Type },
}

struct DerivePartialModel {
Expand Down Expand Up @@ -78,6 +83,7 @@ impl DerivePartialModel {

let mut from_col = None;
let mut from_expr = None;
let flatten = field_attr_contain_key(&field, "flatten");

for attr in field.attrs.iter() {
if !attr.path().is_ident("sea_orm") {
Expand All @@ -100,8 +106,9 @@ impl DerivePartialModel {

let field_name = field.ident.unwrap();

let col_as = match (from_col, from_expr) {
(None, None) => {

let col_as = match (from_col, from_expr, flatten) {
(None, None, false) => {
if entity.is_none() {
return Err(Error::EntityNotSpecific);
}
Expand All @@ -110,19 +117,23 @@ impl DerivePartialModel {
field_name.to_string().to_upper_camel_case()
))
}
(None, Some(expr)) => ColumnAs::Expr {
(None, Some(expr), false) => ColumnAs::Expr {
expr,
field_name: field_name.to_string(),
},
(Some(col), None) => {
(Some(col), None, false) => {
if entity.is_none() {
return Err(Error::EntityNotSpecific);
}

let field = field_name.to_string();
ColumnAs::ColAlias { col, field }
}
(Some(_), Some(_)) => return Err(Error::BothFromColAndFromExpr(field_span)),
(None, None, true) => ColumnAs::Flatten { ty: field.ty },
(Some(_), _, true) | (_, Some(_), true) => {
return Err(Error::FlattenNotOnly(field_span))
}
(Some(_), Some(_), _) => return Err(Error::BothFromColAndFromExpr(field_span)),
};
column_as_list.push(col_as);
}
Expand Down Expand Up @@ -159,6 +170,9 @@ impl DerivePartialModel {
ColumnAs::Expr { expr, field_name } => {
quote!(let #select_ident = sea_orm::SelectColumns::select_column_as(#select_ident, #expr, #field_name);)
},
ColumnAs::Flatten { ty } => {
quote!(let #select_ident = <#ty as sea_orm::PartialModelTrait>::select_cols(#select_ident);)
}
});

quote! {
Expand Down Expand Up @@ -190,6 +204,9 @@ pub fn expand_derive_partial_model(input: syn::DeriveInput) -> syn::Result<Token
Err(Error::InputNotStruct) => Ok(quote_spanned! {
ident_span => compile_error!("you can only derive `DerivePartialModel` on named struct");
}),
Err(Error::FlattenNotOnly(span)) => Ok(quote_spanned! {
span => compile_error!("you can only derive `DerivePartialModel` on named struct");
}),
Err(Error::Syn(err)) => Err(err),
}
}
Expand Down
10 changes: 7 additions & 3 deletions sea-orm-macros/src/derives/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ use quote::format_ident;
use syn::{punctuated::Punctuated, token::Comma, Field, Ident, Meta};

pub(crate) fn field_not_ignored(field: &Field) -> bool {
!field_attr_contain_key(field, "ignore")
}

pub(crate) fn field_attr_contain_key(field: &Field, key: &'static str) -> bool {
for attr in field.attrs.iter() {
if let Some(ident) = attr.path().get_ident() {
if ident != "sea_orm" {
Expand All @@ -16,15 +20,15 @@ pub(crate) fn field_not_ignored(field: &Field) -> bool {
for meta in list.iter() {
if let Meta::Path(path) = meta {
if let Some(name) = path.get_ident() {
if name == "ignore" {
return false;
if name == key {
return true;
}
}
}
}
}
}
true
false
}

pub(crate) fn format_field_ident(field: Field) -> Ident {
Expand Down
56 changes: 56 additions & 0 deletions sea-orm-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,24 @@ pub fn derive_active_enum(input: TokenStream) -> TokenStream {
/// skip_me: i32,
/// }
/// ```
///
/// Can contain other `FromQueryResult` for a complex query result
/// ```
/// use sea_orm::{entity::prelude::*, FromQueryResult};
///
/// #[derive(Debug, FromQueryResult)]
/// struct Foo {
/// bar: i64,
/// }
///
/// #[derive(Debug, FromQueryResult)]
/// struct SelectResult {
/// name: String,
/// num_of_fruits: i32,
/// #[sea_orm(flatten)]
/// foo: Foo,
/// }
/// ```
#[cfg(feature = "derive")]
#[proc_macro_derive(FromQueryResult, attributes(sea_orm))]
pub fn derive_from_query_result(input: TokenStream) -> TokenStream {
Expand Down Expand Up @@ -786,6 +804,44 @@ pub fn derive_from_json_query_result(input: TokenStream) -> TokenStream {
/// sum: i32
/// }
/// ```
///
/// Can contain orther `PartialModel` for complex col constitution
/// ```
/// use sea_orm::{entity::prelude::*, sea_query::Expr, DerivePartialModel, FromQueryResult};
///
/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
/// struct SelectResult {
/// #[sea_orm(from_expr = "Expr::val(1).add(1)")]
/// sum: i32,
/// #[sea_orm(flatten)]
/// foo: Foo,
/// }
///
/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
/// struct Foo {
/// #[sea_orm(from_expr = "Expr::val(12).add(2)")]
/// bar: i64,
/// }
/// ```
/// Note: the `flatten` cannot use with `from_expr` or `from_col`,
/// or is cannot compile
/// ```compile_fail
/// use sea_orm::{entity::prelude::*, sea_query::Expr, DerivePartialModel, FromQueryResult};
///
/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
/// struct SelectResult {
/// #[sea_orm(from_expr = "Expr::val(1).add(1)")]
/// sum: i32,
/// #[sea_orm(flatten, from_expr = "Expr::val(11).div(5)")]
/// foo: Foo
/// }
///
/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
/// struct Foo{
/// #[sea_orm(from_expr = "Expr::val(12).add(2)")]
/// bar: i64
/// }
/// ```
#[cfg(feature = "derive")]
#[proc_macro_derive(DerivePartialModel, attributes(sea_orm))]
pub fn derive_partial_model(input: TokenStream) -> TokenStream {
Expand Down
18 changes: 18 additions & 0 deletions tests/partial_model_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,21 @@ struct FieldFromExpr {
#[sea_orm(from_expr = "Expr::col(Column::Id).equals(Column::Foo)")]
_bar: bool,
}

#[derive(FromQueryResult, DerivePartialModel)]
struct NestWithOther {
#[sea_orm(flatten)]
_flatten1: FieldFromDiffNameColumnTest,
#[sea_orm(flatten)]
_flatten2: FieldFromExpr,
}
#[derive(FromQueryResult, DerivePartialModel)]
#[sea_orm(entity = "Entity")]
struct MixedNestTest {
#[sea_orm(flatten)]
_flatten1: FieldFromDiffNameColumnTest,
#[sea_orm(from_col = "id")]
_id: i32,
#[sea_orm(from_expr = "Column::Bar2.sum()")]
_sum: f64,
}

0 comments on commit a43d781

Please sign in to comment.