Add resolve_into_type_async

This commit is contained in:
nWacky 2019-11-01 17:51:25 +03:00
parent e03e525645
commit 820f472f2c
No known key found for this signature in database
GPG key ID: 22EF2C62F6F79FD0
2 changed files with 39 additions and 15 deletions

View file

@ -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"] }

View file

@ -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<S>: GraphQLType<S> + 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<S>,
executor: &'a Executor<Self::Context, S>,
) -> ExecutionResult<S> {
arguments: &'a Arguments<'a, S>,
executor: &'a Executor<'a, Self::Context, S>,
) -> BoxFuture<'a, ExecutionResult<S>> {
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<S>]>,
executor: &'a Executor<Self::Context, S>,
) -> Value<S> {
selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<'a, Self::Context, S>,
) -> BoxFuture<'a, Value<S>> {
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<S>> {
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 {