From 737c4c718475d8058b0b82a89b8703e406e22ef2 Mon Sep 17 00:00:00 2001 From: nWacky Date: Fri, 1 Nov 2019 17:51:25 +0300 Subject: [PATCH] Add `resolve_into_type_async` --- examples/warp_async/Cargo.toml | 9 ++++--- juniper/src/types/async_await.rs | 45 +++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/examples/warp_async/Cargo.toml b/examples/warp_async/Cargo.toml index 7568b799..d3085ce4 100644 --- a/examples/warp_async/Cargo.toml +++ b/examples/warp_async/Cargo.toml @@ -13,7 +13,10 @@ warp = "0.1.19" futures-preview = { version = "0.3.0-alpha.19", features = ["async-await", "compat"] } reqwest = "0.9.19" -juniper_codegen = { git = "https://github.com/graphql-rust/juniper", branch = "async-await", features = ["async"] } -juniper = { git = "https://github.com/graphql-rust/juniper", branch = "async-await", features = ["async"] } -juniper_warp = { git = "https://github.com/graphql-rust/juniper", branch = "async-await", features = ["async"] } +#juniper_codegen = { git = "https://github.com/graphql-rust/juniper", branch = "async-await", features = ["async"] } +#juniper = { git = "https://github.com/graphql-rust/juniper", branch = "async-await", features = ["async"] } +#juniper_warp = { git = "https://github.com/graphql-rust/juniper", branch = "async-await", features = ["async"] } +juniper_codegen = { path = "../../juniper_codegen", features = ["async"] } +juniper = { path = "../../juniper", features = ["async"] } +juniper_warp = { path = "../../juniper_warp", features = ["async"] } diff --git a/juniper/src/types/async_await.rs b/juniper/src/types/async_await.rs index 3b7971a9..6e87a8cb 100644 --- a/juniper/src/types/async_await.rs +++ b/juniper/src/types/async_await.rs @@ -1,3 +1,4 @@ +use async_trait::async_trait; use crate::{ ast::{Directive, FromInputValue, InputValue, Selection}, value::{Object, ScalarRefValue, ScalarValue, Value}, @@ -12,7 +13,8 @@ use crate::BoxFuture; use super::base::{is_excluded, merge_key_into, Arguments, GraphQLType}; -#[async_trait] +// todo: async trait +//#[async_trait] pub trait GraphQLTypeAsync: GraphQLType + Send + Sync where Self::Context: Send + Sync, @@ -20,28 +22,47 @@ where S: ScalarValue + Send + Sync, for<'b> &'b S: ScalarRefValue<'b>, { - async fn resolve_field_async<'a>( + fn resolve_field_async<'a>( &'a self, info: &'a Self::TypeInfo, field_name: &'a str, - arguments: &'a Arguments, - executor: &'a Executor, - ) -> ExecutionResult { + arguments: &'a Arguments<'a, S>, + executor: &'a Executor<'a, Self::Context, S>, + ) -> BoxFuture<'a, ExecutionResult> { panic!("resolve_field must be implemented by object types"); } - async fn resolve_async<'a>( + fn resolve_async<'a>( &'a self, info: &'a Self::TypeInfo, - selection_set: Option<&'a [Selection]>, - executor: &'a Executor, - ) -> Value { + selection_set: Option<&'a [Selection<'a, S>]>, + executor: &'a Executor<'a, Self::Context, S>, + ) -> BoxFuture<'a, Value> { if let Some(selection_set) = selection_set { resolve_selection_set_into_async(self, info, selection_set, executor) } else { panic!("resolve() must be implemented by non-object output types"); } } + + fn resolve_into_type_async<'a>( + &'a self, + info: &'a Self::TypeInfo, + type_name: &str, + selection_set: Option<&'a [Selection<'a, S>]>, + executor: &'a Executor<'a, Self::Context, S>, + ) -> BoxFuture<'a, ExecutionResult> { + if Self::name(info).unwrap() == type_name { + Box::pin( + async move { + let x = self.resolve_async(info, selection_set, executor).await; + Ok(x) + } + ) + } else { + panic!("resolve_into_type_async must be implemented by unions and interfaces"); + } + } } // Wrapper function around resolve_selection_set_into_async_recursive. @@ -161,7 +182,7 @@ where let response_name = response_name.to_string(); let field_future = async move { // TODO: implement custom future type instead of - // two-level boxing. + // two-level boxing. let res = instance .resolve_field_async(info, f.name.item, &args, &sub_exec) .await; @@ -226,12 +247,12 @@ where if let Some(ref type_condition) = fragment.type_condition { // FIXME: implement async version. - let sub_result = instance.resolve_into_type( + let sub_result = instance.resolve_into_type_async( info, type_condition.item, Some(&fragment.selection_set[..]), &sub_exec, - ); + ).await; if let Ok(Value::Object(obj)) = sub_result { for (k, v) in obj {