From 5eaa58fe2adba7290efb0a142a1b2ccce5839f22 Mon Sep 17 00:00:00 2001 From: greenhandatsjtu Date: Mon, 4 Jul 2022 09:56:23 +0800 Subject: [PATCH] feat: enable convert from ActiveModel to Model --- sea-orm-macros/src/derives/active_model.rs | 57 ++++++++++++++++++++-- src/entity/model.rs | 18 +++++++ src/lib.rs | 8 +-- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/sea-orm-macros/src/derives/active_model.rs b/sea-orm-macros/src/derives/active_model.rs index 635897dcb..73aa4e2bb 100644 --- a/sea-orm-macros/src/derives/active_model.rs +++ b/sea-orm-macros/src/derives/active_model.rs @@ -6,7 +6,8 @@ use syn::{punctuated::Punctuated, token::Comma, Data, DataStruct, Field, Fields, /// Method to derive an [ActiveModel](sea_orm::ActiveModel) pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result { - let fields = match data { + // including ignored fields + let all_fields = match data { Data::Struct(DataStruct { fields: Fields::Named(named), .. @@ -17,8 +18,15 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result = all_fields + .clone() + .into_iter() + .map(|Field { ident, .. }| format_ident!("{}", ident.unwrap().to_string())) + .collect(); let field: Vec = fields .clone() @@ -63,6 +71,27 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result = fields.into_iter().map(|Field { ty, .. }| ty).collect(); + let ignore_attr: Vec = all_fields + .clone() + .map(|field| !field_not_ignored(&field)) + .collect(); + + let field_value: Vec = all_field + .iter() + .zip(ignore_attr) + .map(|(field, ignore)| { + if ignore { + quote! { + Default::default() + } + } else { + quote! { + a.#field.into_value().unwrap().unwrap() + } + } + }) + .collect(); + Ok(quote!( #[derive(Clone, Debug, PartialEq)] pub struct ActiveModel { @@ -92,6 +121,28 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result for ::Model { + type Error = DbErr; + fn try_from(a: ActiveModel) -> Result { + #(if matches!(a.#field, sea_orm::ActiveValue::NotSet) { + return Err(DbErr::Custom(format!("field {} is NotSet", stringify!(#field)))); + })* + Ok( + Self { + #(#all_field: #field_value),* + } + ) + } + } + + #[automatically_derived] + impl sea_orm::TryIntoModel<::Model> for ActiveModel { + fn try_into_model(self) -> Result<::Model, DbErr> { + self.try_into() + } + } + #[automatically_derived] impl sea_orm::ActiveModelTrait for ActiveModel { type Entity = Entity; diff --git a/src/entity/model.rs b/src/entity/model.rs index 34520dc3d..3869ec52f 100644 --- a/src/entity/model.rs +++ b/src/entity/model.rs @@ -115,3 +115,21 @@ pub trait FromQueryResult: Sized { SelectorRaw::>::from_statement(stmt) } } + +/// A Trait for any type that can be converted into an Model +pub trait TryIntoModel +where + M: ModelTrait, +{ + /// Method to call to perform the conversion + fn try_into_model(self) -> Result; +} + +impl TryIntoModel for M +where + M: ModelTrait, +{ + fn try_into_model(self) -> Result { + Ok(self) + } +} diff --git a/src/lib.rs b/src/lib.rs index 36b392c6c..b0604a2cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -261,9 +261,9 @@ //! 1. [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md) //! //! ## Who's using SeaORM? -//! +//! //! The following products are powered by SeaORM: -//! +//! //! //! //! @@ -273,9 +273,9 @@ //! //! //!
-//! +//! //! SeaORM is the foundation of [StarfishQL](https://github.com/SeaQL/starfish-ql), an experimental graph database and query engine developed by SeaQL. -//! +//! //! For more projects, see [Built with SeaORM](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm). //! //! ## License