Add #[sea_orm(skip)] for FromQueryResult macro (#1954)
* Add #[sea_orm(skip)] for FromQueryResult macro * Update sea-orm-rocket * Revert "Update sea-orm-rocket" This reverts commit b7226bb44dbdbab9782524feb0303c4c166d3050.
This commit is contained in:
parent
c81f4d3705
commit
b4010ecb64
@ -1,6 +1,29 @@
|
|||||||
|
use self::util::GetMeta;
|
||||||
use proc_macro2::{Ident, TokenStream};
|
use proc_macro2::{Ident, TokenStream};
|
||||||
use quote::{format_ident, quote, quote_spanned};
|
use quote::{format_ident, quote, quote_spanned, ToTokens};
|
||||||
use syn::{ext::IdentExt, Data, DataStruct, Field, Fields, Generics};
|
use syn::{
|
||||||
|
ext::IdentExt, punctuated::Punctuated, token::Comma, Data, DataStruct, Fields, Generics, Meta,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct FromQueryResultItem {
|
||||||
|
pub skip: bool,
|
||||||
|
pub ident: Ident,
|
||||||
|
}
|
||||||
|
impl ToTokens for FromQueryResultItem {
|
||||||
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
|
let Self { ident, skip } = self;
|
||||||
|
if *skip {
|
||||||
|
tokens.extend(quote! {
|
||||||
|
#ident: std::default::Default::default(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let name = ident.unraw().to_string();
|
||||||
|
tokens.extend(quote! {
|
||||||
|
#ident: row.try_get(pre, #name)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Method to derive a [QueryResult](sea_orm::QueryResult)
|
/// Method to derive a [QueryResult](sea_orm::QueryResult)
|
||||||
pub fn expand_derive_from_query_result(
|
pub fn expand_derive_from_query_result(
|
||||||
@ -19,20 +42,23 @@ pub fn expand_derive_from_query_result(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let mut field = Vec::with_capacity(fields.len());
|
||||||
|
|
||||||
let field: Vec<Ident> = fields
|
for parsed_field in fields.into_iter() {
|
||||||
.into_iter()
|
let mut skip = false;
|
||||||
.map(|Field { ident, .. }| format_ident!("{}", ident.unwrap().to_string()))
|
for attr in parsed_field.attrs.iter() {
|
||||||
.collect();
|
if !attr.path().is_ident("sea_orm") {
|
||||||
|
continue;
|
||||||
let name: Vec<TokenStream> = field
|
}
|
||||||
.iter()
|
if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated) {
|
||||||
.map(|f| {
|
for meta in list.iter() {
|
||||||
let s = f.unraw().to_string();
|
skip = meta.exists("skip");
|
||||||
quote! { #s }
|
}
|
||||||
})
|
}
|
||||||
.collect();
|
}
|
||||||
|
let ident = format_ident!("{}", parsed_field.ident.unwrap().to_string());
|
||||||
|
field.push(FromQueryResultItem { skip, ident });
|
||||||
|
}
|
||||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
Ok(quote!(
|
Ok(quote!(
|
||||||
@ -40,9 +66,25 @@ pub fn expand_derive_from_query_result(
|
|||||||
impl #impl_generics sea_orm::FromQueryResult for #ident #ty_generics #where_clause {
|
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)*
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
mod util {
|
||||||
|
use syn::Meta;
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -579,6 +579,9 @@ pub fn derive_active_enum(input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
/// Convert a query result into the corresponding Model.
|
/// Convert a query result into the corresponding Model.
|
||||||
///
|
///
|
||||||
|
/// ### Attributes
|
||||||
|
/// - `skip`: Will not try to pull this field from the query result. And set it to the default value of the type.
|
||||||
|
///
|
||||||
/// ### Usage
|
/// ### Usage
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -588,10 +591,12 @@ pub fn derive_active_enum(input: TokenStream) -> TokenStream {
|
|||||||
/// struct SelectResult {
|
/// struct SelectResult {
|
||||||
/// name: String,
|
/// name: String,
|
||||||
/// num_of_fruits: i32,
|
/// num_of_fruits: i32,
|
||||||
|
/// #[sea_orm(skip)]
|
||||||
|
/// skip_me: i32,
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "derive")]
|
#[cfg(feature = "derive")]
|
||||||
#[proc_macro_derive(FromQueryResult)]
|
#[proc_macro_derive(FromQueryResult, attributes(sea_orm))]
|
||||||
pub fn derive_from_query_result(input: TokenStream) -> TokenStream {
|
pub fn derive_from_query_result(input: TokenStream) -> TokenStream {
|
||||||
let DeriveInput {
|
let DeriveInput {
|
||||||
ident,
|
ident,
|
||||||
|
@ -56,3 +56,10 @@ where
|
|||||||
{
|
{
|
||||||
_foo: T::Item,
|
_foo: T::Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(FromQueryResult)]
|
||||||
|
struct FromQueryAttributeTests {
|
||||||
|
#[sea_orm(skip)]
|
||||||
|
_foo: i32,
|
||||||
|
_bar: String,
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user