Refactor GraphQLTypeAsync to use async-trait

This commit is contained in:
nWacky 2019-11-01 19:37:55 +03:00
parent 820f472f2c
commit 52c3e281f3
No known key found for this signature in database
GPG key ID: 22EF2C62F6F79FD0
8 changed files with 96 additions and 80 deletions

View file

@ -423,12 +423,16 @@ macro_rules! graphql_scalar {
) )
{ {
fn resolve_async<'a>( fn resolve_async<'a, 'async_trait>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [$crate::Selection<$crate::__juniper_insert_generic!($($scalar)+)>]>, selection_set: Option<&'a [$crate::Selection<'a, $crate::__juniper_insert_generic!($($scalar)+)>]>,
executor: &'a $crate::Executor<Self::Context, $crate::__juniper_insert_generic!($($scalar)+)>, executor: &'a $crate::Executor<'a, Self::Context, $crate::__juniper_insert_generic!($($scalar)+)>,
) -> futures::future::BoxFuture<'a, $crate::Value<$crate::__juniper_insert_generic!($($scalar)+)>> { ) -> futures::future::BoxFuture<'async_trait, $crate::Value<$crate::__juniper_insert_generic!($($scalar)+)>>
where
'a: 'async_trait,
Self: 'async_trait,
{
use $crate::GraphQLType; use $crate::GraphQLType;
use futures::future; use futures::future;
let v = self.resolve(info, selection_set, executor); let v = self.resolve(info, selection_set, executor);

View file

@ -77,6 +77,7 @@ where
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]
#[async_trait::async_trait]
impl<'a, CtxT, S, QueryT, MutationT> crate::GraphQLTypeAsync<S> impl<'a, CtxT, S, QueryT, MutationT> crate::GraphQLTypeAsync<S>
for RootNode<'a, QueryT, MutationT, S> for RootNode<'a, QueryT, MutationT, S>
where where
@ -85,25 +86,25 @@ where
QueryT::TypeInfo: Send + Sync, QueryT::TypeInfo: Send + Sync,
MutationT: crate::GraphQLTypeAsync<S, Context = CtxT>, MutationT: crate::GraphQLTypeAsync<S, Context = CtxT>,
MutationT::TypeInfo: Send + Sync, MutationT::TypeInfo: Send + Sync,
CtxT: Send + Sync, CtxT: Send + Sync + 'a,
for<'b> &'b S: ScalarRefValue<'b>, for<'c> &'c S: ScalarRefValue<'c>,
{ {
fn resolve_field_async<'b>( async fn resolve_field_async<'b>(
&'b self, &'b self,
info: &'b Self::TypeInfo, info: &'b <Self as crate::GraphQLType<S>>::TypeInfo,
field_name: &'b str, field_name: &'b str,
arguments: &'b Arguments<S>, arguments: &'b Arguments<'b, S>,
executor: &'b Executor<Self::Context, S>, executor: &'b Executor<'b, <Self as crate::GraphQLType<S>>::Context, S>,
) -> crate::BoxFuture<'b, ExecutionResult<S>> { ) -> ExecutionResult<S> {
use futures::future::{ready, FutureExt}; use futures::future::{ready, FutureExt};
match field_name { match field_name {
"__schema" | "__type" => { "__schema" | "__type" => {
let v = self.resolve_field(info, field_name, arguments, executor); self.resolve_field(info, field_name, arguments, executor)
Box::pin(ready(v))
} }
_ => self _ => self
.query_type .query_type
.resolve_field_async(info, field_name, arguments, executor), .resolve_field_async(info, field_name, arguments, executor)
.await,
} }
} }
} }

View file

@ -13,8 +13,7 @@ use crate::BoxFuture;
use super::base::{is_excluded, merge_key_into, Arguments, GraphQLType}; use super::base::{is_excluded, merge_key_into, Arguments, GraphQLType};
// todo: async trait #[async_trait]
//#[async_trait]
pub trait GraphQLTypeAsync<S>: GraphQLType<S> + Send + Sync pub trait GraphQLTypeAsync<S>: GraphQLType<S> + Send + Sync
where where
Self::Context: Send + Sync, Self::Context: Send + Sync,
@ -22,43 +21,38 @@ where
S: ScalarValue + Send + Sync, S: ScalarValue + Send + Sync,
for<'b> &'b S: ScalarRefValue<'b>, for<'b> &'b S: ScalarRefValue<'b>,
{ {
fn resolve_field_async<'a>( async fn resolve_field_async<'a>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
field_name: &'a str, field_name: &'a str,
arguments: &'a Arguments<'a, S>, arguments: &'a Arguments<'a, S>,
executor: &'a Executor<'a, Self::Context, S>, executor: &'a Executor<'a, Self::Context, S>,
) -> BoxFuture<'a, ExecutionResult<S>> { ) -> ExecutionResult<S> {
panic!("resolve_field must be implemented by object types"); panic!("resolve_field must be implemented by object types");
} }
fn resolve_async<'a>( async fn resolve_async<'a>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [Selection<'a, S>]>, selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<'a, Self::Context, S>, executor: &'a Executor<'a, Self::Context, S>,
) -> BoxFuture<'a, Value<S>> { ) -> Value<S> {
if let Some(selection_set) = selection_set { if let Some(selection_set) = selection_set {
resolve_selection_set_into_async(self, info, selection_set, executor) resolve_selection_set_into_async(self, info, selection_set, executor).await
} else { } else {
panic!("resolve() must be implemented by non-object output types"); panic!("resolve() must be implemented by non-object output types");
} }
} }
fn resolve_into_type_async<'a>( async fn resolve_into_type_async<'a>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
type_name: &str, type_name: &str,
selection_set: Option<&'a [Selection<'a, S>]>, selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<'a, Self::Context, S>, executor: &'a Executor<'a, Self::Context, S>,
) -> BoxFuture<'a, ExecutionResult<S>> { ) -> ExecutionResult<S> {
if Self::name(info).unwrap() == type_name { if Self::name(info).unwrap() == type_name {
Box::pin( Ok(self.resolve_async(info, selection_set, executor).await)
async move {
let x = self.resolve_async(info, selection_set, executor).await;
Ok(x)
}
)
} else { } else {
panic!("resolve_into_type_async must be implemented by unions and interfaces"); panic!("resolve_into_type_async must be implemented by unions and interfaces");
} }

View file

@ -257,6 +257,7 @@ where
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]
#[async_trait::async_trait]
impl<S, T, CtxT> crate::GraphQLTypeAsync<S> for Vec<T> impl<S, T, CtxT> crate::GraphQLTypeAsync<S> for Vec<T>
where where
T: crate::GraphQLTypeAsync<S, Context = CtxT>, T: crate::GraphQLTypeAsync<S, Context = CtxT>,
@ -265,18 +266,18 @@ where
CtxT: Send + Sync, CtxT: Send + Sync,
for<'b> &'b S: ScalarRefValue<'b>, for<'b> &'b S: ScalarRefValue<'b>,
{ {
fn resolve_async<'a>( async fn resolve_async<'a>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a <Self as crate::GraphQLType<S>>::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<'a, <Self as crate::GraphQLType<S>>::Context, S>,
) -> crate::BoxFuture<'a, Value<S>> { ) -> Value<S> {
let f = resolve_into_list_async(executor, info, self.iter()); resolve_into_list_async(executor, info, self.iter()).await
Box::pin(f)
} }
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]
#[async_trait::async_trait]
impl<S, T, CtxT> crate::GraphQLTypeAsync<S> for &[T] impl<S, T, CtxT> crate::GraphQLTypeAsync<S> for &[T]
where where
T: crate::GraphQLTypeAsync<S, Context = CtxT>, T: crate::GraphQLTypeAsync<S, Context = CtxT>,
@ -285,18 +286,18 @@ where
CtxT: Send + Sync, CtxT: Send + Sync,
for<'b> &'b S: ScalarRefValue<'b>, for<'b> &'b S: ScalarRefValue<'b>,
{ {
fn resolve_async<'a>( async fn resolve_async<'a>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a <Self as crate::GraphQLType<S>>::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<'a, <Self as crate::GraphQLType<S>>::Context, S>,
) -> crate::BoxFuture<'a, Value<S>> { ) -> Value<S> {
let f = resolve_into_list_async(executor, info, self.iter()); resolve_into_list_async(executor, info, self.iter()).await
Box::pin(f)
} }
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]
#[async_trait::async_trait]
impl<S, T, CtxT> crate::GraphQLTypeAsync<S> for Option<T> impl<S, T, CtxT> crate::GraphQLTypeAsync<S> for Option<T>
where where
T: crate::GraphQLTypeAsync<S, Context = CtxT>, T: crate::GraphQLTypeAsync<S, Context = CtxT>,
@ -305,18 +306,15 @@ where
CtxT: Send + Sync, CtxT: Send + Sync,
for<'b> &'b S: ScalarRefValue<'b>, for<'b> &'b S: ScalarRefValue<'b>,
{ {
fn resolve_async<'a>( async fn resolve_async<'a>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a <Self as crate::GraphQLType<S>>::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<'a, <Self as crate::GraphQLType<S>>::Context, S>,
) -> crate::BoxFuture<'a, Value<S>> { ) -> Value<S> {
let f = async move { match *self {
match *self { Some(ref obj) => executor.resolve_into_value_async(info, obj).await,
Some(ref obj) => executor.resolve_into_value_async(info, obj).await, None => Value::null(),
None => Value::null(), }
}
};
Box::pin(f)
} }
} }

View file

@ -137,31 +137,43 @@ where
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]
#[async_trait::async_trait]
impl<'e, S, T> crate::GraphQLTypeAsync<S> for &'e T impl<'e, S, T> crate::GraphQLTypeAsync<S> for &'e T
where where
S: ScalarValue + Send + Sync, S: ScalarValue + Send + Sync,
T: crate::GraphQLTypeAsync<S>, T: crate::GraphQLTypeAsync<S>,
T::TypeInfo: Send + Sync, T::TypeInfo: Send + Sync,
T::Context: Send + Sync, T::Context: Send + Sync,
for<'b> &'b S: ScalarRefValue<'b>, for<'c> &'c S: ScalarRefValue<'c>,
{ {
fn resolve_field_async<'b>( async fn resolve_field_async<'b>(
&'b self, &'b self,
info: &'b Self::TypeInfo, info: &'b <Self as crate::GraphQLType<S>>::TypeInfo,
field_name: &'b str, field_name: &'b str,
arguments: &'b Arguments<S>, arguments: &'b Arguments<'b, S>,
executor: &'b Executor<Self::Context, S>, executor: &'b Executor<'b, <Self as crate::GraphQLType<S>>::Context, S>,
) -> crate::BoxFuture<'b, ExecutionResult<S>> { ) -> ExecutionResult<S> {
crate::GraphQLTypeAsync::resolve_field_async(&**self, info, field_name, arguments, executor) crate::GraphQLTypeAsync::resolve_field_async(
&**self,
info,
field_name,
arguments,
executor
).await
} }
fn resolve_async<'a>( async fn resolve_async<'a>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a <Self as crate::GraphQLType<S>>::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<'a, <Self as crate::GraphQLType<S>>::Context, S>,
) -> crate::BoxFuture<'a, Value<S>> { ) -> Value<S> {
crate::GraphQLTypeAsync::resolve_async(&**self, info, selection_set, executor) crate::GraphQLTypeAsync::resolve_async(
&**self,
info,
selection_set,
executor
).await
} }
} }

View file

@ -197,19 +197,19 @@ where
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]
#[async_trait::async_trait]
impl<'e, S> crate::GraphQLTypeAsync<S> for &'e str impl<'e, S> crate::GraphQLTypeAsync<S> for &'e str
where where
S: ScalarValue + Send + Sync, S: ScalarValue + Send + Sync,
for<'b> &'b S: ScalarRefValue<'b>, for<'b> &'b S: ScalarRefValue<'b>,
{ {
fn resolve_async<'a>( async fn resolve_async<'a>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a <Self as crate::GraphQLType<S>>::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<'a, <Self as crate::GraphQLType<S>>::Context, S>,
) -> crate::BoxFuture<'a, crate::Value<S>> { ) -> crate::Value<S> {
use futures::future; self.resolve(info, selection_set, executor)
future::FutureExt::boxed(future::ready(self.resolve(info, selection_set, executor)))
} }
} }

View file

@ -213,12 +213,16 @@ pub fn impl_enum(ast: &syn::DeriveInput, is_internal: bool) -> TokenStream {
__S: #juniper_path::ScalarValue + Send + Sync, __S: #juniper_path::ScalarValue + Send + Sync,
for<'__b> &'__b __S: #juniper_path::ScalarRefValue<'__b> for<'__b> &'__b __S: #juniper_path::ScalarRefValue<'__b>
{ {
fn resolve_async<'a>( fn resolve_async<'a, 'async_trait>(
&'a self, &'a self,
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [#juniper_path::Selection<__S>]>, selection_set: Option<&'a [#juniper_path::Selection<__S>]>,
executor: &'a #juniper_path::Executor<Self::Context, __S>, executor: &'a #juniper_path::Executor<Self::Context, __S>,
) -> futures::future::BoxFuture<'a, #juniper_path::Value<__S>> { ) -> futures::future::BoxFuture<'async_trait, #juniper_path::Value<__S>>
where
'a: 'async_trait,
Self: 'async_trait
{
use #juniper_path::GraphQLType; use #juniper_path::GraphQLType;
use futures::future; use futures::future;
let v = self.resolve(info, selection_set, executor); let v = self.resolve(info, selection_set, executor);

View file

@ -925,14 +925,17 @@ impl GraphQLTypeDefiniton {
impl#impl_generics #juniper_crate_name::GraphQLTypeAsync<#scalar> for #ty #type_generics_tokens impl#impl_generics #juniper_crate_name::GraphQLTypeAsync<#scalar> for #ty #type_generics_tokens
#where_async #where_async
{ {
fn resolve_field_async<'b>( fn resolve_field_async<'b, 'async_trait>(
&'b self, &'b self,
info: &'b Self::TypeInfo, info: &'b Self::TypeInfo,
field: &'b str, field: &'b str,
args: &'b #juniper_crate_name::Arguments<#scalar>, args: &'b #juniper_crate_name::Arguments<#scalar>,
executor: &'b #juniper_crate_name::Executor<Self::Context, #scalar>, executor: &'b #juniper_crate_name::Executor<Self::Context, #scalar>,
) -> futures::future::BoxFuture<'b, #juniper_crate_name::ExecutionResult<#scalar>> ) -> futures::future::BoxFuture<'async_trait, #juniper_crate_name::ExecutionResult<#scalar>>
where #scalar: Send + Sync, where
#scalar: Send + Sync,
'b: 'async_trait,
Self: 'async_trait,
{ {
use futures::future; use futures::future;
use #juniper_crate_name::GraphQLType; use #juniper_crate_name::GraphQLType;