From 6ae515961c15e4bdee93bb16ba23606401a49f3c Mon Sep 17 00:00:00 2001 From: Iskandarov Lev Date: Tue, 11 Apr 2023 07:23:14 +0400 Subject: [PATCH] implemented (#1464) --- .../src/derives/from_query_result.rs | 17 +++++-- sea-orm-macros/src/lib.rs | 9 +++- tests/derive_tests.rs | 46 +++++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 tests/derive_tests.rs diff --git a/sea-orm-macros/src/derives/from_query_result.rs b/sea-orm-macros/src/derives/from_query_result.rs index 12b856718..765884aaf 100644 --- a/sea-orm-macros/src/derives/from_query_result.rs +++ b/sea-orm-macros/src/derives/from_query_result.rs @@ -1,9 +1,13 @@ use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote, quote_spanned}; -use syn::{ext::IdentExt, Data, DataStruct, Field, Fields}; +use syn::{ext::IdentExt, parse_quote, Data, DataStruct, Field, Fields, GenericParam, Generics}; /// Method to derive a [QueryResult](sea_orm::QueryResult) -pub fn expand_derive_from_query_result(ident: Ident, data: Data) -> syn::Result { +pub fn expand_derive_from_query_result( + ident: Ident, + data: Data, + mut generics: Generics, +) -> syn::Result { let fields = match data { Data::Struct(DataStruct { fields: Fields::Named(named), @@ -29,9 +33,16 @@ pub fn expand_derive_from_query_result(ident: Ident, data: Data) -> syn::Result< }) .collect(); + for param in &mut generics.params { + if let GenericParam::Type(type_param) = param { + type_param.bounds.push(parse_quote!(sea_orm::TryGetable)); + } + } + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + Ok(quote!( #[automatically_derived] - impl sea_orm::FromQueryResult for #ident { + impl #impl_generics sea_orm::FromQueryResult for #ident #ty_generics #where_clause { fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> std::result::Result { Ok(Self { #(#field: row.try_get(pre, #name)?),* diff --git a/sea-orm-macros/src/lib.rs b/sea-orm-macros/src/lib.rs index 6a795d76f..cd8d04a26 100644 --- a/sea-orm-macros/src/lib.rs +++ b/sea-orm-macros/src/lib.rs @@ -592,9 +592,14 @@ pub fn derive_active_enum(input: TokenStream) -> TokenStream { #[cfg(feature = "derive")] #[proc_macro_derive(FromQueryResult)] pub fn derive_from_query_result(input: TokenStream) -> TokenStream { - let DeriveInput { ident, data, .. } = parse_macro_input!(input); + let DeriveInput { + ident, + data, + generics, + .. + } = parse_macro_input!(input); - match derives::expand_derive_from_query_result(ident, data) { + match derives::expand_derive_from_query_result(ident, data, generics) { Ok(ts) => ts.into(), Err(e) => e.to_compile_error().into(), } diff --git a/tests/derive_tests.rs b/tests/derive_tests.rs new file mode 100644 index 000000000..5e3738ff2 --- /dev/null +++ b/tests/derive_tests.rs @@ -0,0 +1,46 @@ +use sea_orm::{FromQueryResult, TryGetable}; + +#[derive(FromQueryResult)] +struct SimpleTest { + _foo: i32, + _bar: String, +} + +#[derive(FromQueryResult)] +struct GenericTest { + _foo: i32, + _bar: T, +} + +#[derive(FromQueryResult)] +struct DoubleGenericTest { + _foo: T, + _bar: F, +} + +#[derive(FromQueryResult)] +struct BoundsGenericTest { + _foo: T, +} + +#[derive(FromQueryResult)] +struct WhereGenericTest +where + T: Copy + Clone + 'static, +{ + _foo: T, +} + +#[derive(FromQueryResult)] +struct AlreadySpecifiedBoundsGenericTest { + _foo: T, +} + +#[derive(FromQueryResult)] +struct MixedGenericTest +where + F: Copy + Clone + 'static, +{ + _foo: T, + _bar: F, +}