Fix can no longer derive Union for union types with lifetimes. #311
This commit is contained in:
parent
bc5cf2f2a2
commit
b054f1bf9f
|
@ -56,9 +56,7 @@ This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in
|
|||
|
||||
## Examples
|
||||
|
||||
If you are just getting started, we recommend checking out our examples at: https://github.com/async-graphql/examples
|
||||
|
||||
To see how you would create a Relay-compliant server using async-graphql, warp, diesel & postgresql, you can also check out a real-world example at: https://github.com/phated/twentyfive-stars
|
||||
https://github.com/async-graphql/examples
|
||||
|
||||
## Benchmark
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ use proc_macro::TokenStream;
|
|||
use proc_macro2::{Ident, Span};
|
||||
use quote::quote;
|
||||
use std::collections::HashSet;
|
||||
use syn::{Error, Type};
|
||||
use syn::visit_mut::VisitMut;
|
||||
use syn::{visit_mut, Error, Lifetime, Type};
|
||||
|
||||
pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream> {
|
||||
let crate_name = get_crate_name(interface_args.internal);
|
||||
|
@ -71,7 +72,20 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
|||
);
|
||||
}
|
||||
|
||||
struct RemoveLifetime;
|
||||
impl VisitMut for RemoveLifetime {
|
||||
fn visit_lifetime_mut(&mut self, i: &mut Lifetime) {
|
||||
i.ident = Ident::new("_", Span::call_site());
|
||||
visit_mut::visit_lifetime_mut(self, i);
|
||||
}
|
||||
}
|
||||
|
||||
let mut assert_ty = p.clone();
|
||||
RemoveLifetime.visit_type_path_mut(&mut assert_ty);
|
||||
|
||||
type_into_impls.push(quote! {
|
||||
#crate_name::static_assertions::assert_impl_one!(#assert_ty: #crate_name::ObjectType);
|
||||
|
||||
#[allow(clippy::all, clippy::pedantic)]
|
||||
impl #generics ::std::convert::From<#p> for #ident #generics {
|
||||
fn from(obj: #p) -> Self {
|
||||
|
@ -322,7 +336,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
fn collect_all_fields<'a>(&'a self, ctx: &#crate_name::ContextSelectionSet<'a>, fields: &mut #crate_name::resolver_utils::Fields<'a>) -> #crate_name::ServerResult<()> {
|
||||
fn collect_all_fields<'__life>(&'__life self, ctx: &#crate_name::ContextSelectionSet<'__life>, fields: &mut #crate_name::resolver_utils::Fields<'__life>) -> #crate_name::ServerResult<()> {
|
||||
match self {
|
||||
#(#collect_all_fields),*
|
||||
}
|
||||
|
|
|
@ -77,10 +77,10 @@ pub fn generate(object_args: &args::MergedSubscription) -> GeneratorResult<Token
|
|||
|
||||
#[allow(clippy::all, clippy::pedantic)]
|
||||
impl #crate_name::SubscriptionType for #ident {
|
||||
fn create_field_stream<'a>(
|
||||
&'a self,
|
||||
ctx: &'a #crate_name::Context<'a>
|
||||
) -> Option<::std::pin::Pin<::std::boxed::Box<dyn #crate_name::futures::Stream<Item = #crate_name::ServerResult<#crate_name::Value>> + ::std::marker::Send + 'a>>> {
|
||||
fn create_field_stream<'__life>(
|
||||
&'__life self,
|
||||
ctx: &'__life #crate_name::Context<'__life>
|
||||
) -> Option<::std::pin::Pin<::std::boxed::Box<dyn #crate_name::futures::Stream<Item = #crate_name::ServerResult<#crate_name::Value>> + ::std::marker::Send + '__life>>> {
|
||||
None #create_field_stream
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
|||
|
||||
let expanded = quote! {
|
||||
#[allow(clippy::all, clippy::pedantic)]
|
||||
impl #generics #ident #where_clause {
|
||||
impl #generics #ident #generics #where_clause {
|
||||
#(#getters)*
|
||||
}
|
||||
|
||||
|
|
|
@ -388,10 +388,10 @@ pub fn generate(
|
|||
#[allow(clippy::all, clippy::pedantic)]
|
||||
#[allow(unused_braces, unused_variables)]
|
||||
impl #crate_name::SubscriptionType for #self_ty #where_clause {
|
||||
fn create_field_stream<'a>(
|
||||
&'a self,
|
||||
ctx: &'a #crate_name::Context<'a>,
|
||||
) -> ::std::option::Option<::std::pin::Pin<::std::boxed::Box<dyn #crate_name::futures::Stream<Item = #crate_name::ServerResult<#crate_name::Value>> + Send + 'a>>> {
|
||||
fn create_field_stream<'__life>(
|
||||
&'__life self,
|
||||
ctx: &'__life #crate_name::Context<'__life>,
|
||||
) -> ::std::option::Option<::std::pin::Pin<::std::boxed::Box<dyn #crate_name::futures::Stream<Item = #crate_name::ServerResult<#crate_name::Value>> + Send + '__life>>> {
|
||||
#(#create_stream)*
|
||||
None
|
||||
}
|
||||
|
|
|
@ -2,9 +2,11 @@ use crate::args::{self, RenameTarget};
|
|||
use crate::utils::{get_crate_name, get_rustdoc, GeneratorResult};
|
||||
use darling::ast::{Data, Style};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::{Ident, Span};
|
||||
use quote::quote;
|
||||
use std::collections::HashSet;
|
||||
use syn::{Error, Type};
|
||||
use syn::visit_mut::VisitMut;
|
||||
use syn::{visit_mut, Error, Lifetime, Type};
|
||||
|
||||
pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||
let crate_name = get_crate_name(union_args.internal);
|
||||
|
@ -68,9 +70,20 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
|||
|
||||
enum_names.push(enum_name);
|
||||
|
||||
struct RemoveLifetime;
|
||||
impl VisitMut for RemoveLifetime {
|
||||
fn visit_lifetime_mut(&mut self, i: &mut Lifetime) {
|
||||
i.ident = Ident::new("_", Span::call_site());
|
||||
visit_mut::visit_lifetime_mut(self, i);
|
||||
}
|
||||
}
|
||||
|
||||
let mut assert_ty = p.clone();
|
||||
RemoveLifetime.visit_type_path_mut(&mut assert_ty);
|
||||
|
||||
if !variant.flatten {
|
||||
type_into_impls.push(quote! {
|
||||
#crate_name::static_assertions::assert_impl_one!(#p: #crate_name::ObjectType);
|
||||
#crate_name::static_assertions::assert_impl_one!(#assert_ty: #crate_name::ObjectType);
|
||||
|
||||
#[allow(clippy::all, clippy::pedantic)]
|
||||
impl #generics ::std::convert::From<#p> for #ident #generics {
|
||||
|
@ -81,7 +94,7 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
|||
});
|
||||
} else {
|
||||
type_into_impls.push(quote! {
|
||||
#crate_name::static_assertions::assert_impl_one!(#p: #crate_name::UnionType);
|
||||
#crate_name::static_assertions::assert_impl_one!(#assert_ty: #crate_name::UnionType);
|
||||
|
||||
#[allow(clippy::all, clippy::pedantic)]
|
||||
impl #generics ::std::convert::From<#p> for #ident #generics {
|
||||
|
@ -167,7 +180,7 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
fn collect_all_fields<'a>(&'a self, ctx: &#crate_name::ContextSelectionSet<'a>, fields: &mut #crate_name::resolver_utils::Fields<'a>) -> #crate_name::ServerResult<()> {
|
||||
fn collect_all_fields<'__life>(&'__life self, ctx: &#crate_name::ContextSelectionSet<'__life>, fields: &mut #crate_name::resolver_utils::Fields<'__life>) -> #crate_name::ServerResult<()> {
|
||||
match self {
|
||||
#(#collect_all_fields),*
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ let schema = Schema::new(
|
|||
);
|
||||
```
|
||||
|
||||
> ⚠️ **MergedObject cannot be used in Interface。**
|
||||
|
||||
# Merging Subscriptions
|
||||
|
||||
Along with `MergedObject`, you can derive `MergedSubscription` or use `#[MergedSubscription]` to merge separate `#[Subscription]` blocks.
|
||||
|
|
|
@ -49,6 +49,8 @@ let schema = Schema::new(
|
|||
);
|
||||
```
|
||||
|
||||
> ⚠️ **合并的对象无法在Interface中使用。**
|
||||
|
||||
# 合并订阅
|
||||
|
||||
和`MergedObject`一样,你可以派生`MergedSubscription`来合并单独的`#[Subscription]`块。
|
||||
|
|
|
@ -92,12 +92,8 @@
|
|||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! If you are just getting started, we recommend checking out our examples at:
|
||||
//! [https://github.com/async-graphql/examples](https://github.com/async-graphql/examples)
|
||||
//!
|
||||
//! To see how you would create a Relay-compliant server using async-graphql, warp, diesel & postgresql, you can also check out a real-world example at:
|
||||
//! [https://github.com/phated/twentyfive-stars](https://github.com/phated/twentyfive-stars)
|
||||
//!
|
||||
//! ## Benchmarks
|
||||
//!
|
||||
//! Ensure that there is no CPU-heavy process in background!
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
use async_graphql::*;
|
||||
use static_assertions::_core::marker::PhantomData;
|
||||
|
||||
#[derive(SimpleObject)]
|
||||
struct ObjA<'a> {
|
||||
value: &'a i32,
|
||||
}
|
||||
|
||||
struct ObjB<'a>(PhantomData<&'a i32>);
|
||||
|
||||
#[Object]
|
||||
impl<'a> ObjB<'a> {
|
||||
async fn value(&self) -> &'a i32 {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Union)]
|
||||
enum MyUnion1<'a> {
|
||||
ObjA(ObjA<'a>),
|
||||
}
|
||||
|
||||
#[derive(Interface)]
|
||||
#[graphql(field(name = "value", type = "&&'a i32"))]
|
||||
enum MyInterface<'a> {
|
||||
ObjA(ObjA<'a>),
|
||||
}
|
Loading…
Reference in New Issue