From 639c29e91ed015cb7cca275cb8549c6f25174cd9 Mon Sep 17 00:00:00 2001 From: tyranron Date: Wed, 9 Oct 2019 20:11:34 +0200 Subject: [PATCH 1/3] Upgrade futures-preview, tokio crates and remove unnecessary 'async_await' feature --- examples/warp_async/Cargo.toml | 2 +- examples/warp_async/src/main.rs | 2 +- integration_tests/async_await/Cargo.toml | 4 ++-- integration_tests/async_await/src/main.rs | 6 +++--- juniper/Cargo.toml | 4 ++-- juniper/src/lib.rs | 2 +- juniper_benchmarks/Cargo.toml | 4 ++-- juniper_benchmarks/src/lib.rs | 2 +- juniper_rocket/Cargo.toml | 3 ++- juniper_rocket/src/lib.rs | 15 ++++++--------- juniper_warp/Cargo.toml | 2 +- juniper_warp/src/lib.rs | 2 +- 12 files changed, 23 insertions(+), 25 deletions(-) diff --git a/examples/warp_async/Cargo.toml b/examples/warp_async/Cargo.toml index c33445e8..7568b799 100644 --- a/examples/warp_async/Cargo.toml +++ b/examples/warp_async/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" log = "0.4.8" env_logger = "0.6.2" warp = "0.1.19" -futures-preview = { version = "0.3.0-alpha.18", features = ["nightly", "async-await", "compat"] } +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"] } diff --git a/examples/warp_async/src/main.rs b/examples/warp_async/src/main.rs index 170d743b..6b53ff38 100644 --- a/examples/warp_async/src/main.rs +++ b/examples/warp_async/src/main.rs @@ -2,7 +2,7 @@ //! This example demonstrates async/await usage with warp. //! NOTE: this uses tokio 0.1 , not the alpha tokio 0.2. -#![feature(async_await, async_closure)] +#![feature(async_closure)] use juniper::{EmptyMutation, RootNode, FieldError}; use warp::{http::Response, Filter}; diff --git a/integration_tests/async_await/Cargo.toml b/integration_tests/async_await/Cargo.toml index 3bbc0436..2207cf04 100644 --- a/integration_tests/async_await/Cargo.toml +++ b/integration_tests/async_await/Cargo.toml @@ -8,5 +8,5 @@ edition = "2018" [dependencies] juniper = { path = "../../juniper", features = ["async"] } -futures-preview = "0.3.0-alpha.18" -tokio = "0.2.0-alpha.2" +futures-preview = "=0.3.0-alpha.19" +tokio = "=0.2.0-alpha.6" diff --git a/integration_tests/async_await/src/main.rs b/integration_tests/async_await/src/main.rs index cbdfc4e3..eed72dff 100644 --- a/integration_tests/async_await/src/main.rs +++ b/integration_tests/async_await/src/main.rs @@ -1,4 +1,4 @@ -#![feature(async_await, async_closure)] +#![feature(async_closure)] use juniper::{graphql_value, RootNode, Value}; @@ -38,7 +38,7 @@ impl User { async fn delayed() -> bool { let when = tokio::clock::now() + std::time::Duration::from_millis(100); - tokio::timer::Delay::new(when).await; + tokio::timer::delay(when).await; true } } @@ -65,7 +65,7 @@ impl Query { async fn delayed() -> bool { let when = tokio::clock::now() + std::time::Duration::from_millis(100); - tokio::timer::Delay::new(when).await; + tokio::timer::delay(when).await; true } } diff --git a/juniper/Cargo.toml b/juniper/Cargo.toml index e3bf3120..b7d62c94 100644 --- a/juniper/Cargo.toml +++ b/juniper/Cargo.toml @@ -45,9 +45,9 @@ serde_json = { version="1.0.2", optional = true } url = { version = "1.5.1", optional = true } uuid = { version = "0.7", optional = true } -futures-preview = { version = "0.3.0-alpha.18", optional = true, features = ["nightly", "async-await"] } +futures-preview = { version = "=0.3.0-alpha.19", optional = true } [dev-dependencies] bencher = "0.1.2" serde_json = { version = "1.0.2" } -tokio = "0.2.0-alpha.2" +tokio = "=0.2.0-alpha.6" diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index ca0a4dc5..c4510863 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -91,7 +91,7 @@ Juniper has not reached 1.0 yet, thus some API instability should be expected. #![doc(html_root_url = "https://docs.rs/juniper/0.13.1")] #![warn(missing_docs)] -#![cfg_attr(feature = "async", feature(async_await, async_closure))] +#![cfg_attr(feature = "async", feature(async_closure))] #[doc(hidden)] pub extern crate serde; diff --git a/juniper_benchmarks/Cargo.toml b/juniper_benchmarks/Cargo.toml index e4da5478..df10da20 100644 --- a/juniper_benchmarks/Cargo.toml +++ b/juniper_benchmarks/Cargo.toml @@ -12,8 +12,8 @@ harness = false [dependencies] juniper = { path = "../juniper", features = ["async"] } -futures-preview = "0.3.0-alpha.18" +futures-preview = "=0.3.0-alpha.19" [dev-dependencies] criterion = "0.2.11" -tokio = "0.2.0-alpha.2" +tokio = "=0.2.0-alpha.6" diff --git a/juniper_benchmarks/src/lib.rs b/juniper_benchmarks/src/lib.rs index a9f2aa4b..65c3b20a 100644 --- a/juniper_benchmarks/src/lib.rs +++ b/juniper_benchmarks/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(async_await, async_closure)] +#![feature(async_closure)] use juniper::{ object, DefaultScalarValue, ExecutionError, FieldError, GraphQLEnum, Value, Variables, diff --git a/juniper_rocket/Cargo.toml b/juniper_rocket/Cargo.toml index 737aca70..cad056bc 100644 --- a/juniper_rocket/Cargo.toml +++ b/juniper_rocket/Cargo.toml @@ -20,8 +20,9 @@ serde_json = { version = "1.0.2" } serde_derive = { version = "1.0.2" } juniper = { version = "0.13.1" , default-features = false, path = "../juniper"} -futures03 = { version = "0.3.0-alpha.18", package = "futures-preview", features = ["compat"] } +futures03 = { version = "=0.3.0-alpha.19", package = "futures-preview", features = ["compat"] } rocket = { git = "https://github.com/SergioBenitez/Rocket", branch = "async" } +tokio = "=0.2.0-alpha.6" [dev-dependencies.juniper] version = "0.13.1" diff --git a/juniper_rocket/src/lib.rs b/juniper_rocket/src/lib.rs index 88cf619d..68817cb1 100644 --- a/juniper_rocket/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -38,18 +38,15 @@ Check the LICENSE file for details. #![doc(html_root_url = "https://docs.rs/juniper_rocket/0.2.0")] #![feature(decl_macro, proc_macro_hygiene)] -#![cfg_attr(feature = "async", feature(async_await, async_closure))] +#![cfg_attr(feature = "async", feature(async_closure))] -use std::{ - error::Error, - io::{Cursor, Read}, -}; +use std::{error::Error, io::Cursor}; use rocket::{ - data::{FromDataSimple, Outcome as FromDataOutcome}, + data::{FromDataFuture, FromDataSimple}, http::{ContentType, RawStr, Status}, request::{FormItems, FromForm, FromFormValue}, - response::{content, Responder, Response}, + response::{content, Responder, Response, ResultFuture}, Data, Outcome::{Failure, Forward, Success}, Request, @@ -400,8 +397,8 @@ where type Error = String; fn from_data(request: &Request, data: Data) -> FromDataFuture<'static, Self, Self::Error> { - use futures03::io::AsyncReadExt; - use rocket::AsyncReadExt as _; + use tokio::io::AsyncReadExt as _; + if !request.content_type().map_or(false, |ct| ct.is_json()) { return Box::pin(async move { Forward(data) }); } diff --git a/juniper_warp/Cargo.toml b/juniper_warp/Cargo.toml index 04805c21..72b48689 100644 --- a/juniper_warp/Cargo.toml +++ b/juniper_warp/Cargo.toml @@ -21,7 +21,7 @@ futures = "0.1.23" serde = "1.0.75" tokio-threadpool = "0.1.7" -futures03 = { version = "0.3.0-alpha.18", optional = true, package = "futures-preview", features = ["compat"] } +futures03 = { version = "=0.3.0-alpha.19", optional = true, package = "futures-preview", features = ["compat"] } [dev-dependencies] juniper = { version = "0.13.1", path = "../juniper", features = ["expose-test-schema", "serde_json"] } diff --git a/juniper_warp/src/lib.rs b/juniper_warp/src/lib.rs index a8725b29..b00a9b6c 100644 --- a/juniper_warp/src/lib.rs +++ b/juniper_warp/src/lib.rs @@ -39,7 +39,7 @@ Check the LICENSE file for details. #![deny(missing_docs)] #![deny(warnings)] #![doc(html_root_url = "https://docs.rs/juniper_warp/0.2.0")] -#![cfg_attr(feature = "async", feature(async_await, async_closure))] +#![cfg_attr(feature = "async", feature(async_closure))] use futures::{future::poll_fn, Future}; use serde::Deserialize; From 5d3ed9ac726a3e44960941b8caaddc0c172db100 Mon Sep 17 00:00:00 2001 From: tyranron Date: Thu, 10 Oct 2019 00:07:10 +0200 Subject: [PATCH 2/3] Remove async_closure feature usage --- examples/warp_async/src/main.rs | 2 - integration_tests/async_await/src/main.rs | 2 - juniper/src/lib.rs | 1 - juniper_benchmarks/src/lib.rs | 2 - juniper_codegen/src/derive_object.rs | 2 +- juniper_codegen/src/impl_object.rs | 29 +---- juniper_codegen/src/util.rs | 142 +++++++++++----------- juniper_rocket/src/lib.rs | 1 - juniper_warp/src/lib.rs | 1 - 9 files changed, 74 insertions(+), 108 deletions(-) diff --git a/examples/warp_async/src/main.rs b/examples/warp_async/src/main.rs index 6b53ff38..a7142d4e 100644 --- a/examples/warp_async/src/main.rs +++ b/examples/warp_async/src/main.rs @@ -2,8 +2,6 @@ //! This example demonstrates async/await usage with warp. //! NOTE: this uses tokio 0.1 , not the alpha tokio 0.2. -#![feature(async_closure)] - use juniper::{EmptyMutation, RootNode, FieldError}; use warp::{http::Response, Filter}; diff --git a/integration_tests/async_await/src/main.rs b/integration_tests/async_await/src/main.rs index eed72dff..feb68bca 100644 --- a/integration_tests/async_await/src/main.rs +++ b/integration_tests/async_await/src/main.rs @@ -1,5 +1,3 @@ -#![feature(async_closure)] - use juniper::{graphql_value, RootNode, Value}; #[derive(juniper::GraphQLEnum)] diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index c4510863..f1c7c2a1 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -91,7 +91,6 @@ Juniper has not reached 1.0 yet, thus some API instability should be expected. #![doc(html_root_url = "https://docs.rs/juniper/0.13.1")] #![warn(missing_docs)] -#![cfg_attr(feature = "async", feature(async_closure))] #[doc(hidden)] pub extern crate serde; diff --git a/juniper_benchmarks/src/lib.rs b/juniper_benchmarks/src/lib.rs index 65c3b20a..4a79da2f 100644 --- a/juniper_benchmarks/src/lib.rs +++ b/juniper_benchmarks/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(async_closure)] - use juniper::{ object, DefaultScalarValue, ExecutionError, FieldError, GraphQLEnum, Value, Variables, }; diff --git a/juniper_codegen/src/derive_object.rs b/juniper_codegen/src/derive_object.rs index c6042aa7..911a21cb 100644 --- a/juniper_codegen/src/derive_object.rs +++ b/juniper_codegen/src/derive_object.rs @@ -59,7 +59,7 @@ pub fn build_derive_object(ast: syn::DeriveInput, is_internal: bool) -> TokenStr description: field_attrs.description, deprecation: field_attrs.deprecation, resolver_code, - resolver_code_async: None, + is_async: false, }) } }); diff --git a/juniper_codegen/src/impl_object.rs b/juniper_codegen/src/impl_object.rs index 992e3570..eb3f5c0f 100644 --- a/juniper_codegen/src/impl_object.rs +++ b/juniper_codegen/src/impl_object.rs @@ -197,29 +197,10 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) -> } let body = &method.block; - let return_ty = &method.sig.output; - - let (resolver_code, resolver_code_async) = if is_async { - ( - quote!(), - Some(quote!( - (async move || #return_ty { - #( #resolve_parts )* - #body - })() - )), - ) - } else { - ( - quote!( - (|| #return_ty { - #( #resolve_parts )* - #body - })() - ), - None, - ) - }; + let resolver_code = quote!( + #( #resolve_parts )* + #body + ); let ident = &method.sig.ident; let name = attrs @@ -233,7 +214,7 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) -> description: attrs.description, deprecation: attrs.deprecation, resolver_code, - resolver_code_async, + is_async, }); } _ => { diff --git a/juniper_codegen/src/util.rs b/juniper_codegen/src/util.rs index 1e7fee83..1f1a4d66 100644 --- a/juniper_codegen/src/util.rs +++ b/juniper_codegen/src/util.rs @@ -592,14 +592,7 @@ pub struct GraphQLTypeDefinitionField { pub deprecation: Option, pub args: Vec, pub resolver_code: proc_macro2::TokenStream, - pub resolver_code_async: Option, -} - -impl GraphQLTypeDefinitionField { - #[inline] - fn is_async(&self) -> bool { - self.resolver_code_async.is_some() - } + pub is_async: bool, } /// Definition of a graphql type based on information extracted @@ -633,7 +626,7 @@ pub struct GraphQLTypeDefiniton { impl GraphQLTypeDefiniton { fn has_async_field(&self) -> bool { - self.fields.iter().any(|field| field.is_async()) + self.fields.iter().any(|field| field.is_async) } pub fn into_tokens(self, juniper_crate_name: &str) -> proc_macro2::TokenStream { @@ -706,7 +699,7 @@ impl GraphQLTypeDefiniton { let name = &field.name; let code = &field.resolver_code; - if field.is_async() { + if field.is_async { // TODO: better error message with field/type name. quote!( #name => { @@ -714,9 +707,10 @@ impl GraphQLTypeDefiniton { }, ) } else { + let _type = &field._type; quote!( #name => { - let res = { #code }; + let res: #_type = { #code }; #juniper_crate_name::IntoResolvable::into( res, executor.context() @@ -805,74 +799,74 @@ impl GraphQLTypeDefiniton { #[cfg(feature = "async")] let resolve_field_async = { let resolve_matches_async = self.fields.iter().map(|field| { - let name = &field.name; + let name = &field.name; + let _type = &field._type; + let code = &field.resolver_code; - if let Some(code) = field.resolver_code_async.as_ref() { - quote!( - #name => { - let f = async move { - let res = { #code }.await; + if field.is_async { + quote!( + #name => { + let f = async move { + let res: #_type = async move { #code }.await; - let inner_res = #juniper_crate_name::IntoResolvable::into( - res, - executor.context() - ); - match inner_res { - Ok(Some((ctx, r))) => { - let subexec = executor - .replaced_context(ctx); - subexec.resolve_with_ctx_async(&(), &r) - .await - }, - Ok(None) => Ok(#juniper_crate_name::Value::null()), - Err(e) => Err(e), - } - }; - future::FutureExt::boxed(f) - }, - ) - } else { - let code = &field.resolver_code; - - let inner = if !self.no_async { - quote!( - let f = async move { - match res2 { - Ok(Some((ctx, r))) => { - let sub = executor.replaced_context(ctx); - sub.resolve_with_ctx_async(&(), &r).await - }, - Ok(None) => Ok(#juniper_crate_name::Value::null()), - Err(e) => Err(e), - } - }; - future::FutureExt::boxed(f) - ) - } else { - quote!( - let v = match res2 { - Ok(Some((ctx, r))) => executor.replaced_context(ctx).resolve_with_ctx(&(), &r), - Ok(None) => Ok(#juniper_crate_name::Value::null()), - Err(e) => Err(e), - }; - future::FutureExt::boxed(future::ready(v)) - ) + let inner_res = #juniper_crate_name::IntoResolvable::into( + res, + executor.context() + ); + match inner_res { + Ok(Some((ctx, r))) => { + let subexec = executor + .replaced_context(ctx); + subexec.resolve_with_ctx_async(&(), &r) + .await + }, + Ok(None) => Ok(#juniper_crate_name::Value::null()), + Err(e) => Err(e), + } }; + future::FutureExt::boxed(f) + }, + ) + } else { + let inner = if !self.no_async { + quote!( + let f = async move { + match res2 { + Ok(Some((ctx, r))) => { + let sub = executor.replaced_context(ctx); + sub.resolve_with_ctx_async(&(), &r).await + }, + Ok(None) => Ok(#juniper_crate_name::Value::null()), + Err(e) => Err(e), + } + }; + future::FutureExt::boxed(f) + ) + } else { + quote!( + let v = match res2 { + Ok(Some((ctx, r))) => executor.replaced_context(ctx).resolve_with_ctx(&(), &r), + Ok(None) => Ok(#juniper_crate_name::Value::null()), + Err(e) => Err(e), + }; + future::FutureExt::boxed(future::ready(v)) + ) + }; - quote!( - #name => { - let res = { #code }; - let res2 = #juniper_crate_name::IntoResolvable::into( - res, - executor.context() - ); - #inner - }, - ) - } - }); + quote!( + #name => { + let res: #_type = { #code }; + let res2 = #juniper_crate_name::IntoResolvable::into( + res, + executor.context() + ); + #inner + }, + ) + } + }); - let mut where_async = where_clause.cloned().unwrap_or_else(|| parse_quote!(where));; + let mut where_async = where_clause.cloned().unwrap_or_else(|| parse_quote!(where)); where_async .predicates diff --git a/juniper_rocket/src/lib.rs b/juniper_rocket/src/lib.rs index 68817cb1..dd57769a 100644 --- a/juniper_rocket/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -38,7 +38,6 @@ Check the LICENSE file for details. #![doc(html_root_url = "https://docs.rs/juniper_rocket/0.2.0")] #![feature(decl_macro, proc_macro_hygiene)] -#![cfg_attr(feature = "async", feature(async_closure))] use std::{error::Error, io::Cursor}; diff --git a/juniper_warp/src/lib.rs b/juniper_warp/src/lib.rs index b00a9b6c..55d423fd 100644 --- a/juniper_warp/src/lib.rs +++ b/juniper_warp/src/lib.rs @@ -39,7 +39,6 @@ Check the LICENSE file for details. #![deny(missing_docs)] #![deny(warnings)] #![doc(html_root_url = "https://docs.rs/juniper_warp/0.2.0")] -#![cfg_attr(feature = "async", feature(async_closure))] use futures::{future::poll_fn, Future}; use serde::Deserialize; From e2903cf0f7cbb19949646e35a88310301c04e8ec Mon Sep 17 00:00:00 2001 From: tyranron Date: Thu, 10 Oct 2019 14:50:10 +0200 Subject: [PATCH 3/3] Fix type inferring for trivial resolver code Additionally: - fix inconsistencies after merge with master --- juniper/src/executor/mod.rs | 117 +-------------------------- juniper_codegen/src/derive_object.rs | 1 + juniper_codegen/src/impl_object.rs | 1 + juniper_codegen/src/util.rs | 21 +++-- 4 files changed, 22 insertions(+), 118 deletions(-) diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index 27300882..2fdcd4fd 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -828,121 +828,10 @@ where None => return Err(GraphQLError::UnknownOperationName), }; - let default_variable_values = op.item.variable_definitions.map(|defs| { - defs.item - .items - .iter() - .filter_map(|&(ref name, ref def)| { - def.default_value - .as_ref() - .map(|i| (name.item.to_owned(), i.item.clone())) - }) - .collect::>>() - }); - - let errors = RwLock::new(Vec::new()); - let value; - - { - let mut all_vars; - let mut final_vars = variables; - - if let Some(defaults) = default_variable_values { - all_vars = variables.clone(); - - for (name, value) in defaults { - all_vars.entry(name).or_insert(value); - } - - final_vars = &all_vars; - } - - let root_type = match op.item.operation_type { - OperationType::Query => root_node.schema.query_type(), - OperationType::Mutation => root_node - .schema - .mutation_type() - .expect("No mutation type found"), - }; - - let executor = Executor { - fragments: &fragments - .iter() - .map(|f| (f.item.name.item, &f.item)) - .collect(), - variables: final_vars, - current_selection_set: Some(&op.item.selection_set[..]), - parent_selection_set: None, - current_type: root_type, - schema: &root_node.schema, - context, - errors: &errors, - field_path: FieldPath::Root(op.start), - }; - - value = match op.item.operation_type { - OperationType::Query => { - executor - .resolve_into_value_async(&root_node.query_info, &root_node) - .await - } - OperationType::Mutation => { - executor - .resolve_into_value_async(&root_node.mutation_info, &root_node.mutation_type) - .await - } - }; + if op.item.operation_type == OperationType::Subscription { + return Err(GraphQLError::IsSubscription); } - let mut errors = errors.into_inner().unwrap(); - errors.sort(); - - Ok((value, errors)) -} - -#[cfg(feature = "async")] -pub async fn execute_validated_query_async<'a, QueryT, MutationT, CtxT, S>( - document: Document<'a, S>, - operation_name: Option<&str>, - root_node: &RootNode<'a, QueryT, MutationT, S>, - variables: &Variables, - context: &CtxT, -) -> Result<(Value, Vec>), GraphQLError<'a>> -where - S: ScalarValue + Send + Sync, - QueryT: crate::GraphQLTypeAsync + Send + Sync, - QueryT::TypeInfo: Send + Sync, - MutationT: crate::GraphQLTypeAsync + Send + Sync, - MutationT::TypeInfo: Send + Sync, - CtxT: Send + Sync, - for<'b> &'b S: ScalarRefValue<'b>, -{ - let mut fragments = vec![]; - let mut operation = None; - - for def in document { - match def { - Definition::Operation(op) => { - if operation_name.is_none() && operation.is_some() { - return Err(GraphQLError::MultipleOperationsProvided); - } - - let move_op = operation_name.is_none() - || op.item.name.as_ref().map(|s| s.item) == operation_name; - - if move_op { - operation = Some(op); - } - } - Definition::Fragment(f) => fragments.push(f), - }; - } - - let op = match operation { - Some(op) => op, - None => return Err(GraphQLError::UnknownOperationName), - }; - let default_variable_values = op.item.variable_definitions.map(|defs| { defs.item .items @@ -978,6 +867,7 @@ where .schema .mutation_type() .expect("No mutation type found"), + OperationType::Subscription => unreachable!(), }; let executor = Executor { @@ -1006,6 +896,7 @@ where .resolve_into_value_async(&root_node.mutation_info, &root_node.mutation_type) .await } + OperationType::Subscription => unreachable!(), }; } diff --git a/juniper_codegen/src/derive_object.rs b/juniper_codegen/src/derive_object.rs index 911a21cb..f7a4110f 100644 --- a/juniper_codegen/src/derive_object.rs +++ b/juniper_codegen/src/derive_object.rs @@ -59,6 +59,7 @@ pub fn build_derive_object(ast: syn::DeriveInput, is_internal: bool) -> TokenStr description: field_attrs.description, deprecation: field_attrs.deprecation, resolver_code, + is_type_inferred: true, is_async: false, }) } diff --git a/juniper_codegen/src/impl_object.rs b/juniper_codegen/src/impl_object.rs index eb3f5c0f..88822cc7 100644 --- a/juniper_codegen/src/impl_object.rs +++ b/juniper_codegen/src/impl_object.rs @@ -214,6 +214,7 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) -> description: attrs.description, deprecation: attrs.deprecation, resolver_code, + is_type_inferred: false, is_async, }); } diff --git a/juniper_codegen/src/util.rs b/juniper_codegen/src/util.rs index 875b0df6..a0dae69e 100644 --- a/juniper_codegen/src/util.rs +++ b/juniper_codegen/src/util.rs @@ -597,6 +597,7 @@ pub struct GraphQLTypeDefinitionField { pub deprecation: Option, pub args: Vec, pub resolver_code: proc_macro2::TokenStream, + pub is_type_inferred: bool, pub is_async: bool, } @@ -712,10 +713,15 @@ impl GraphQLTypeDefiniton { }, ) } else { - let _type = &field._type; + let _type = if field.is_type_inferred { + quote!() + } else { + let _type = &field._type; + quote!(: #_type) + }; quote!( #name => { - let res: #_type = { #code }; + let res #_type = { #code }; #juniper_crate_name::IntoResolvable::into( res, executor.context() @@ -805,14 +811,19 @@ impl GraphQLTypeDefiniton { let resolve_field_async = { let resolve_matches_async = self.fields.iter().map(|field| { let name = &field.name; - let _type = &field._type; let code = &field.resolver_code; + let _type = if field.is_type_inferred { + quote!() + } else { + let _type = &field._type; + quote!(: #_type) + }; if field.is_async { quote!( #name => { let f = async move { - let res: #_type = async move { #code }.await; + let res #_type = async move { #code }.await; let inner_res = #juniper_crate_name::IntoResolvable::into( res, @@ -860,7 +871,7 @@ impl GraphQLTypeDefiniton { quote!( #name => { - let res: #_type = { #code }; + let res #_type = { #code }; let res2 = #juniper_crate_name::IntoResolvable::into( res, executor.context()