implemented (#1464)

This commit is contained in:
Iskandarov Lev 2023-04-11 07:23:14 +04:00 committed by GitHub
parent a26dfc8ef7
commit 6ae515961c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 5 deletions

View File

@ -1,9 +1,13 @@
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote, quote_spanned}; 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) /// Method to derive a [QueryResult](sea_orm::QueryResult)
pub fn expand_derive_from_query_result(ident: Ident, data: Data) -> syn::Result<TokenStream> { pub fn expand_derive_from_query_result(
ident: Ident,
data: Data,
mut generics: Generics,
) -> syn::Result<TokenStream> {
let fields = match data { let fields = match data {
Data::Struct(DataStruct { Data::Struct(DataStruct {
fields: Fields::Named(named), fields: Fields::Named(named),
@ -29,9 +33,16 @@ pub fn expand_derive_from_query_result(ident: Ident, data: Data) -> syn::Result<
}) })
.collect(); .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!( Ok(quote!(
#[automatically_derived] #[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<Self, sea_orm::DbErr> { fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> std::result::Result<Self, sea_orm::DbErr> {
Ok(Self { Ok(Self {
#(#field: row.try_get(pre, #name)?),* #(#field: row.try_get(pre, #name)?),*

View File

@ -592,9 +592,14 @@ pub fn derive_active_enum(input: TokenStream) -> TokenStream {
#[cfg(feature = "derive")] #[cfg(feature = "derive")]
#[proc_macro_derive(FromQueryResult)] #[proc_macro_derive(FromQueryResult)]
pub fn derive_from_query_result(input: TokenStream) -> TokenStream { 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(), Ok(ts) => ts.into(),
Err(e) => e.to_compile_error().into(), Err(e) => e.to_compile_error().into(),
} }

46
tests/derive_tests.rs Normal file
View File

@ -0,0 +1,46 @@
use sea_orm::{FromQueryResult, TryGetable};
#[derive(FromQueryResult)]
struct SimpleTest {
_foo: i32,
_bar: String,
}
#[derive(FromQueryResult)]
struct GenericTest<T> {
_foo: i32,
_bar: T,
}
#[derive(FromQueryResult)]
struct DoubleGenericTest<T, F> {
_foo: T,
_bar: F,
}
#[derive(FromQueryResult)]
struct BoundsGenericTest<T: Copy + Clone + 'static> {
_foo: T,
}
#[derive(FromQueryResult)]
struct WhereGenericTest<T>
where
T: Copy + Clone + 'static,
{
_foo: T,
}
#[derive(FromQueryResult)]
struct AlreadySpecifiedBoundsGenericTest<T: TryGetable> {
_foo: T,
}
#[derive(FromQueryResult)]
struct MixedGenericTest<T: Clone, F>
where
F: Copy + Clone + 'static,
{
_foo: T,
_bar: F,
}