Merge pull request #452 from instrumentisto/async-await-resolve-some-todos
Resolve some todos in async-await branch
This commit is contained in:
commit
b133a0f3c2
32 changed files with 373 additions and 184 deletions
benches
examples/warp_async/src
juniper
juniper_codegen
juniper_hyper
juniper_iron
juniper_rocket
juniper_warp
127
benches/bench.rs
Normal file
127
benches/bench.rs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
#[macro_use] extern crate bencher;
|
||||||
|
extern crate juniper;
|
||||||
|
|
||||||
|
use bencher::Bencher;
|
||||||
|
|
||||||
|
use juniper::{execute, RootNode, EmptyMutation, Variables};
|
||||||
|
use juniper::tests::model::Database;
|
||||||
|
|
||||||
|
fn query_type_name(b: &mut Bencher) {
|
||||||
|
let database = Database::new();
|
||||||
|
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
|
||||||
|
|
||||||
|
let doc = r#"
|
||||||
|
query IntrospectionQueryTypeQuery {
|
||||||
|
__schema {
|
||||||
|
queryType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
b.iter(|| execute(doc, None, &schema, &Variables::new(), &database));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn introspection_query(b: &mut Bencher) {
|
||||||
|
let database = Database::new();
|
||||||
|
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
|
||||||
|
|
||||||
|
let doc = r#"
|
||||||
|
query IntrospectionQuery {
|
||||||
|
__schema {
|
||||||
|
queryType { name }
|
||||||
|
mutationType { name }
|
||||||
|
subscriptionType { name }
|
||||||
|
types {
|
||||||
|
...FullType
|
||||||
|
}
|
||||||
|
directives {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
locations
|
||||||
|
args {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment FullType on __Type {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
description
|
||||||
|
fields(includeDeprecated: true) {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
args {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
type {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
isDeprecated
|
||||||
|
deprecationReason
|
||||||
|
}
|
||||||
|
inputFields {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
interfaces {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
enumValues(includeDeprecated: true) {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
isDeprecated
|
||||||
|
deprecationReason
|
||||||
|
}
|
||||||
|
possibleTypes {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment InputValue on __InputValue {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
type { ...TypeRef }
|
||||||
|
defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment TypeRef on __Type {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
b.iter(|| execute(doc, None, &schema, &Variables::new(), &database));
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_group!(queries, query_type_name, introspection_query);
|
||||||
|
benchmark_main!(queries);
|
|
@ -43,7 +43,7 @@ impl User {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Query;
|
struct Query;
|
||||||
|
|
||||||
#[juniper::object(Context = Context)]
|
#[juniper::object(Context = Context)]
|
||||||
impl Query {
|
impl Query {
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
- No changes yet
|
- No changes yet
|
||||||
|
|
||||||
|
# [[0.14.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.1)
|
||||||
|
|
||||||
|
- Fix panic when an invalid scalar is used by a client [#434](https://github.com/graphql-rust/juniper/pull/434)
|
||||||
|
- `EmptyMutation` now implements `Send` [#443](https://github.com/graphql-rust/juniper/pull/443)
|
||||||
|
|
||||||
# [[0.14.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.0)
|
# [[0.14.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.0)
|
||||||
|
|
||||||
- Require `url` 2.x if `url` feature is enabled.
|
- Require `url` 2.x if `url` feature is enabled.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "juniper"
|
name = "juniper"
|
||||||
version = "0.14.0"
|
version = "0.14.1"
|
||||||
authors = [
|
authors = [
|
||||||
"Magnus Hallin <mhallin@fastmail.com>",
|
"Magnus Hallin <mhallin@fastmail.com>",
|
||||||
"Christoph Herzog <chris@theduke.at>",
|
"Christoph Herzog <chris@theduke.at>",
|
||||||
|
@ -33,20 +33,19 @@ default = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
juniper_codegen = { version = "0.14.0", path = "../juniper_codegen" }
|
juniper_codegen = { version = "0.14.1", path = "../juniper_codegen" }
|
||||||
|
|
||||||
|
async-trait = "0.1.16"
|
||||||
|
chrono = { version = "0.4.0", optional = true }
|
||||||
fnv = "1.0.3"
|
fnv = "1.0.3"
|
||||||
|
futures-preview = { version = "=0.3.0-alpha.19", optional = true }
|
||||||
indexmap = { version = "1.0.0", features = ["serde-1"] }
|
indexmap = { version = "1.0.0", features = ["serde-1"] }
|
||||||
serde = { version = "1.0.8" }
|
serde = { version = "1.0.8" }
|
||||||
serde_derive = { version = "1.0.2" }
|
serde_derive = { version = "1.0.2" }
|
||||||
|
|
||||||
chrono = { version = "0.4.0", optional = true }
|
|
||||||
serde_json = { version="1.0.2", optional = true }
|
serde_json = { version="1.0.2", optional = true }
|
||||||
url = { version = "2", optional = true }
|
url = { version = "2", optional = true }
|
||||||
uuid = { version = "0.7", optional = true }
|
uuid = { version = "0.7", optional = true }
|
||||||
|
|
||||||
futures-preview = { version = "=0.3.0-alpha.19", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bencher = "0.1.2"
|
bencher = "0.1.2"
|
||||||
serde_json = { version = "1.0.2" }
|
serde_json = { version = "1.0.2" }
|
||||||
|
|
|
@ -210,20 +210,6 @@ impl<S> FieldError<S> {
|
||||||
/// The result of resolving the value of a field of type `T`
|
/// The result of resolving the value of a field of type `T`
|
||||||
pub type FieldResult<T, S = DefaultScalarValue> = Result<T, FieldError<S>>;
|
pub type FieldResult<T, S = DefaultScalarValue> = Result<T, FieldError<S>>;
|
||||||
|
|
||||||
/*
|
|
||||||
pub enum ResolvedValue<'a, S = DefaultScalarValue> {
|
|
||||||
Value(Value<S>),
|
|
||||||
Future(crate::BoxFuture<'a, Value<S>>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, S> From<Value<S>> for ResolvedValue<'a, S> {
|
|
||||||
#[inline]
|
|
||||||
fn from(value: Value<S>) -> Self {
|
|
||||||
ResolvedValue::Value(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// The result of resolving an unspecified field
|
/// The result of resolving an unspecified field
|
||||||
pub type ExecutionResult<S = DefaultScalarValue> = Result<Value<S>, FieldError<S>>;
|
pub type ExecutionResult<S = DefaultScalarValue> = Result<Value<S>, FieldError<S>>;
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ Juniper has not reached 1.0 yet, thus some API instability should be expected.
|
||||||
[chrono]: https://crates.io/crates/chrono
|
[chrono]: https://crates.io/crates/chrono
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#![doc(html_root_url = "https://docs.rs/juniper/0.14.0")]
|
#![doc(html_root_url = "https://docs.rs/juniper/0.14.1")]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
|
@ -96,25 +96,6 @@ macro_rules! __juniper_insert_generic {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove me.
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! __juniper_extract_generic {
|
|
||||||
(<$name:ident>) => {
|
|
||||||
$name
|
|
||||||
};
|
|
||||||
(
|
|
||||||
<$generic:tt $(: $bound: tt)*>
|
|
||||||
) => {
|
|
||||||
$generic
|
|
||||||
};
|
|
||||||
(
|
|
||||||
$scalar: ty
|
|
||||||
) => {
|
|
||||||
$scalar
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! __juniper_parse_object_header {
|
macro_rules! __juniper_parse_object_header {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -73,13 +73,17 @@ impl Root {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: enable once [RFC 2565](https://github.com/rust-lang/rust/issues/60406) is implemented
|
// TODO: enable once [parameter attributes are supported by proc macros]
|
||||||
// fn attr_arg_descr(#[doc = "The arg"] arg: i32) -> i32 { 0 }
|
// (https://github.com/graphql-rust/juniper/pull/441)
|
||||||
// fn attr_arg_descr_collapse(
|
// fn attr_arg_descr(
|
||||||
// #[doc = "The arg"]
|
// #[graphql(description = "The arg")]
|
||||||
// #[doc = "and more details"]
|
// arg: i32) -> i32
|
||||||
// arg: i32,
|
// { 0 }
|
||||||
// ) -> i32 { 0 }
|
// fn attr_arg_descr_collapse(
|
||||||
|
// #[graphql(description = "The first arg")]
|
||||||
|
// #[graphql(description = "and more details")]
|
||||||
|
// arg: i32,
|
||||||
|
// ) -> i32 { 0 }
|
||||||
|
|
||||||
#[graphql(arguments(arg(default = 123,),))]
|
#[graphql(arguments(arg(default = 123,),))]
|
||||||
fn arg_with_default(arg: i32) -> i32 {
|
fn arg_with_default(arg: i32) -> i32 {
|
||||||
|
@ -559,7 +563,8 @@ fn introspect_field_multi_args_descr_trailing_comma() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: enable once [RFC 2565](https://github.com/rust-lang/rust/issues/60406) is implemented
|
// TODO: enable once [parameter attributes are supported by proc macros]
|
||||||
|
// (https://github.com/graphql-rust/juniper/pull/441)
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn introspect_field_attr_arg_descr() {
|
// fn introspect_field_attr_arg_descr() {
|
||||||
// run_args_info_query("attrArgDescr", |args| {
|
// run_args_info_query("attrArgDescr", |args| {
|
||||||
|
@ -593,7 +598,8 @@ fn introspect_field_multi_args_descr_trailing_comma() {
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// TODO: enable once [RFC 2565](https://github.com/rust-lang/rust/issues/60406) is implemented
|
// TODO: enable once [parameter attributes are supported by proc macros]
|
||||||
|
// (https://github.com/graphql-rust/juniper/pull/441)
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn introspect_field_attr_arg_descr_collapse() {
|
// fn introspect_field_attr_arg_descr_collapse() {
|
||||||
// run_args_info_query("attrArgDescrCollapse", |args| {
|
// run_args_info_query("attrArgDescrCollapse", |args| {
|
||||||
|
|
|
@ -13,6 +13,9 @@ pub enum ParseError<'a> {
|
||||||
|
|
||||||
/// An error during tokenization occurred
|
/// An error during tokenization occurred
|
||||||
LexerError(LexerError),
|
LexerError(LexerError),
|
||||||
|
|
||||||
|
/// A scalar of unexpected type occurred in the source
|
||||||
|
ExpectedScalarError(&'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -196,6 +199,7 @@ impl<'a> fmt::Display for ParseError<'a> {
|
||||||
ParseError::UnexpectedToken(ref token) => write!(f, "Unexpected \"{}\"", token),
|
ParseError::UnexpectedToken(ref token) => write!(f, "Unexpected \"{}\"", token),
|
||||||
ParseError::UnexpectedEndOfFile => write!(f, "Unexpected end of input"),
|
ParseError::UnexpectedEndOfFile => write!(f, "Unexpected end of input"),
|
||||||
ParseError::LexerError(ref err) => err.fmt(f),
|
ParseError::LexerError(ref err) => err.fmt(f),
|
||||||
|
ParseError::ExpectedScalarError(err) => err.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
parser::{document::parse_document_source, ParseError, SourcePosition, Spanning, Token},
|
parser::{document::parse_document_source, ParseError, SourcePosition, Spanning, Token},
|
||||||
schema::model::SchemaType,
|
schema::model::SchemaType,
|
||||||
|
types::scalars::EmptyMutation,
|
||||||
validation::test_harness::{MutationRoot, QueryRoot},
|
validation::test_harness::{MutationRoot, QueryRoot},
|
||||||
value::{DefaultScalarValue, ScalarRefValue, ScalarValue},
|
value::{DefaultScalarValue, ScalarRefValue, ScalarValue},
|
||||||
};
|
};
|
||||||
|
@ -145,3 +146,23 @@ fn errors() {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn issue_427_panic_is_not_expected() {
|
||||||
|
struct QueryWithoutFloat;
|
||||||
|
|
||||||
|
#[crate::object_internal]
|
||||||
|
impl QueryWithoutFloat {
|
||||||
|
fn echo(value: String) -> String {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let schema = SchemaType::new::<QueryWithoutFloat, EmptyMutation<()>>(&(), &());
|
||||||
|
let parse_result = parse_document_source(r##"{ echo(value: 123.0) }"##, &schema);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse_result.unwrap_err().item,
|
||||||
|
ParseError::ExpectedScalarError("There needs to be a Float type")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -210,33 +210,36 @@ fn parse_scalar_literal_by_infered_type<'a, 'b, S>(
|
||||||
where
|
where
|
||||||
S: ScalarValue,
|
S: ScalarValue,
|
||||||
{
|
{
|
||||||
match token {
|
let result = match token {
|
||||||
ScalarToken::String(_) => {
|
ScalarToken::String(_) => {
|
||||||
if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("String") {
|
if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("String") {
|
||||||
(s.parse_fn)(token)
|
(s.parse_fn)(token).map(InputValue::Scalar)
|
||||||
.map(|s| Spanning::start_end(start, end, InputValue::Scalar(s)))
|
|
||||||
.map_err(|e| Spanning::start_end(start, end, e))
|
|
||||||
} else {
|
} else {
|
||||||
panic!("There needs to be a String type")
|
Err(ParseError::ExpectedScalarError(
|
||||||
|
"There needs to be a String type",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScalarToken::Int(_) => {
|
ScalarToken::Int(_) => {
|
||||||
if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("Int") {
|
if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("Int") {
|
||||||
(s.parse_fn)(token)
|
(s.parse_fn)(token).map(InputValue::Scalar)
|
||||||
.map(|s| Spanning::start_end(start, end, InputValue::Scalar(s)))
|
|
||||||
.map_err(|e| Spanning::start_end(start, end, e))
|
|
||||||
} else {
|
} else {
|
||||||
panic!("There needs to be a Int type")
|
Err(ParseError::ExpectedScalarError(
|
||||||
|
"There needs to be an Int type",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScalarToken::Float(_) => {
|
ScalarToken::Float(_) => {
|
||||||
if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("Float") {
|
if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("Float") {
|
||||||
(s.parse_fn)(token)
|
(s.parse_fn)(token).map(InputValue::Scalar)
|
||||||
.map(|s| Spanning::start_end(start, end, InputValue::Scalar(s)))
|
|
||||||
.map_err(|e| Spanning::start_end(start, end, e))
|
|
||||||
} else {
|
} else {
|
||||||
panic!("There needs to be a Float type")
|
Err(ParseError::ExpectedScalarError(
|
||||||
|
"There needs to be a Float type",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
result
|
||||||
|
.map(|s| Spanning::start_end(start, end, s))
|
||||||
|
.map_err(|e| Spanning::start_end(start, end, e))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,16 +86,16 @@ 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" => {
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::BoxFuture;
|
||||||
|
|
||||||
use super::base::{is_excluded, merge_key_into, Arguments, GraphQLType};
|
use super::base::{is_excluded, merge_key_into, Arguments, GraphQLType};
|
||||||
|
|
||||||
|
#[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,
|
||||||
|
@ -19,28 +20,42 @@ 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<S>,
|
arguments: &'a Arguments<'a, S>,
|
||||||
executor: &'a Executor<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<S>]>,
|
selection_set: Option<&'a [Selection<'a, S>]>,
|
||||||
executor: &'a Executor<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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async 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>,
|
||||||
|
) -> ExecutionResult<S> {
|
||||||
|
if Self::name(info).unwrap() == type_name {
|
||||||
|
Ok(self.resolve_async(info, selection_set, executor).await)
|
||||||
|
} else {
|
||||||
|
panic!("resolve_into_type_async must be implemented by unions and interfaces");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper function around resolve_selection_set_into_async_recursive.
|
// Wrapper function around resolve_selection_set_into_async_recursive.
|
||||||
|
@ -160,7 +175,7 @@ where
|
||||||
let response_name = response_name.to_string();
|
let response_name = response_name.to_string();
|
||||||
let field_future = async move {
|
let field_future = async move {
|
||||||
// TODO: implement custom future type instead of
|
// TODO: implement custom future type instead of
|
||||||
// two-level boxing.
|
// two-level boxing.
|
||||||
let res = instance
|
let res = instance
|
||||||
.resolve_field_async(info, f.name.item, &args, &sub_exec)
|
.resolve_field_async(info, f.name.item, &args, &sub_exec)
|
||||||
.await;
|
.await;
|
||||||
|
@ -223,14 +238,14 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(ref type_condition) = fragment.type_condition {
|
if let Some(ref type_condition) = fragment.type_condition {
|
||||||
// FIXME: implement async version.
|
let sub_result = instance
|
||||||
|
.resolve_into_type_async(
|
||||||
let sub_result = instance.resolve_into_type(
|
info,
|
||||||
info,
|
type_condition.item,
|
||||||
type_condition.item,
|
Some(&fragment.selection_set[..]),
|
||||||
Some(&fragment.selection_set[..]),
|
&sub_exec,
|
||||||
&sub_exec,
|
)
|
||||||
);
|
.await;
|
||||||
|
|
||||||
if let Ok(Value::Object(obj)) = sub_result {
|
if let Ok(Value::Object(obj)) = sub_result {
|
||||||
for (k, v) in obj {
|
for (k, v) in obj {
|
||||||
|
|
|
@ -343,7 +343,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_selection_set_into<T, CtxT, S>(
|
pub(crate) fn resolve_selection_set_into<T, CtxT, S>(
|
||||||
instance: &T,
|
instance: &T,
|
||||||
info: &T::TypeInfo,
|
info: &T::TypeInfo,
|
||||||
selection_set: &[Selection<S>],
|
selection_set: &[Selection<S>],
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,31 +137,33 @@ 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +308,9 @@ impl<T> EmptyMutation<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is safe due to never using `T`.
|
||||||
|
unsafe impl<T> Send for EmptyMutation<T> {}
|
||||||
|
|
||||||
impl<S, T> GraphQLType<S> for EmptyMutation<T>
|
impl<S, T> GraphQLType<S> for EmptyMutation<T>
|
||||||
where
|
where
|
||||||
S: ScalarValue,
|
S: ScalarValue,
|
||||||
|
@ -343,7 +346,7 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::ID;
|
use super::{EmptyMutation, ID};
|
||||||
use crate::{
|
use crate::{
|
||||||
parser::ScalarToken,
|
parser::ScalarToken,
|
||||||
value::{DefaultScalarValue, ParseScalarValue},
|
value::{DefaultScalarValue, ParseScalarValue},
|
||||||
|
@ -390,4 +393,10 @@ mod tests {
|
||||||
"unicode \u{1234}\u{5678}\u{90ab}\u{cdef}",
|
"unicode \u{1234}\u{5678}\u{90ab}\u{cdef}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_mutation_is_send() {
|
||||||
|
fn check_if_send<T: Send>() {}
|
||||||
|
check_if_send::<EmptyMutation<()>>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,8 +260,6 @@ pub enum DefaultScalarValue {
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
trait S: Send + Sync {}
|
|
||||||
|
|
||||||
impl ScalarValue for DefaultScalarValue {
|
impl ScalarValue for DefaultScalarValue {
|
||||||
type Visitor = DefaultScalarValueVisitor;
|
type Visitor = DefaultScalarValueVisitor;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "juniper_codegen"
|
name = "juniper_codegen"
|
||||||
version = "0.14.0"
|
version = "0.14.1"
|
||||||
authors = [
|
authors = [
|
||||||
"Magnus Hallin <mhallin@fastmail.com>",
|
"Magnus Hallin <mhallin@fastmail.com>",
|
||||||
"Christoph Herzog <chris@theduke.at>",
|
"Christoph Herzog <chris@theduke.at>",
|
||||||
|
@ -24,7 +24,7 @@ quote = "1.0.2"
|
||||||
proc-macro-error = "0.3.4"
|
proc-macro-error = "0.3.4"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
juniper = { version = "0.14.0", path = "../juniper" }
|
juniper = { version = "0.14.1", path = "../juniper" }
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
travis-ci = { repository = "graphql-rust/juniper" }
|
travis-ci = { repository = "graphql-rust/juniper" }
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -42,8 +42,7 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let name =
|
let name = if let Some(name) = impl_attrs.name.as_ref(){
|
||||||
if let Some(name) = impl_attrs.name.as_ref(){
|
|
||||||
name.to_string()
|
name.to_string()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
|
||||||
use proc_macro_error::MacroError;
|
use proc_macro_error::MacroError;
|
||||||
use quote::{quote};
|
use quote::quote;
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
|
|
||||||
use crate::util;
|
use crate::util;
|
||||||
|
@ -39,7 +39,7 @@ impl syn::parse::Parse for ResolveBody {
|
||||||
body.parse::<syn::token::Match>()?;
|
body.parse::<syn::token::Match>()?;
|
||||||
body.parse::<syn::token::SelfValue>()?;
|
body.parse::<syn::token::SelfValue>()?;
|
||||||
|
|
||||||
let match_body;
|
let match_body;
|
||||||
syn::braced!( match_body in body );
|
syn::braced!( match_body in body );
|
||||||
|
|
||||||
let mut variants = Vec::new();
|
let mut variants = Vec::new();
|
||||||
|
@ -154,7 +154,7 @@ pub fn impl_union(
|
||||||
let context = attrs.context.map(|c| quote!{ #c } ).unwrap_or_else(|| quote!{ () });
|
let context = attrs.context.map(|c| quote!{ #c } ).unwrap_or_else(|| quote!{ () });
|
||||||
|
|
||||||
let output = quote! {
|
let output = quote! {
|
||||||
impl #impl_generics #juniper::GraphQLType<#scalar> for #ty #where_clause
|
impl #impl_generics #juniper::GraphQLType<#scalar> for #ty #where_clause
|
||||||
{
|
{
|
||||||
type Context = #context;
|
type Context = #context;
|
||||||
type TypeInfo = ();
|
type TypeInfo = ();
|
||||||
|
|
|
@ -731,15 +731,31 @@ impl GraphQLTypeDefiniton {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let scalar = self
|
||||||
|
.scalar
|
||||||
|
.as_ref()
|
||||||
|
.map(|s| quote!( #s ))
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
if self.generic_scalar {
|
||||||
|
// If generic_scalar is true, we always insert a generic scalar.
|
||||||
|
// See more comments below.
|
||||||
|
quote!(__S)
|
||||||
|
} else {
|
||||||
|
quote!(#juniper_crate_name::DefaultScalarValue)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let resolve_matches = self.fields.iter().map(|field| {
|
let resolve_matches = self.fields.iter().map(|field| {
|
||||||
let name = &field.name;
|
let name = &field.name;
|
||||||
let code = &field.resolver_code;
|
let code = &field.resolver_code;
|
||||||
|
|
||||||
if field.is_async {
|
if field.is_async {
|
||||||
// TODO: better error message with field/type name.
|
|
||||||
quote!(
|
quote!(
|
||||||
#name => {
|
#name => {
|
||||||
panic!("Tried to resolve async field with a sync resolver");
|
panic!("Tried to resolve async field {} on type {:?} with a sync resolver",
|
||||||
|
#name,
|
||||||
|
<Self as #juniper_crate_name::GraphQLType<#scalar>>::name(_info)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -780,20 +796,6 @@ impl GraphQLTypeDefiniton {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let scalar = self
|
|
||||||
.scalar
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| quote!( #s ))
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
if self.generic_scalar {
|
|
||||||
// If generic_scalar is true, we always insert a generic scalar.
|
|
||||||
// See more comments below.
|
|
||||||
quote!(__S)
|
|
||||||
} else {
|
|
||||||
quote!(#juniper_crate_name::DefaultScalarValue)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Preserve the original type_generics before modification,
|
// Preserve the original type_generics before modification,
|
||||||
// since alteration makes them invalid if self.generic_scalar
|
// since alteration makes them invalid if self.generic_scalar
|
||||||
// is specified.
|
// is specified.
|
||||||
|
@ -925,21 +927,27 @@ 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;
|
||||||
match field {
|
match field {
|
||||||
#( #resolve_matches_async )*
|
#( #resolve_matches_async )*
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Field {} not found on type {}", field, "Mutation");
|
panic!("Field {} not found on type {:?}",
|
||||||
|
field,
|
||||||
|
<Self as #juniper_crate_name::GraphQLType<#scalar>>::name(info)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -989,7 +997,10 @@ impl GraphQLTypeDefiniton {
|
||||||
match field {
|
match field {
|
||||||
#( #resolve_matches )*
|
#( #resolve_matches )*
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Field {} not found on type {}", field, "Mutation");
|
panic!("Field {} not found on type {:?}",
|
||||||
|
field,
|
||||||
|
<Self as #juniper_crate_name::GraphQLType<#scalar>>::name(_info)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
- Compatibility with the latest `juniper`.
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
||||||
|
# [[0.5.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.5.1)
|
||||||
|
|
||||||
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
||||||
# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.5.0)
|
# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.5.0)
|
||||||
|
|
||||||
- Compatibility with the latest `juniper`.
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "juniper_hyper"
|
name = "juniper_hyper"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
authors = ["Damir Vandic <info@dvic.io>"]
|
authors = ["Damir Vandic <info@dvic.io>"]
|
||||||
description = "Juniper GraphQL integration with Hyper"
|
description = "Juniper GraphQL integration with Hyper"
|
||||||
license = "BSD-2-Clause"
|
license = "BSD-2-Clause"
|
||||||
|
@ -13,7 +13,7 @@ serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
url = "2"
|
url = "2"
|
||||||
juniper = { version = "0.14.0", default-features = false, path = "../juniper"}
|
juniper = { version = "0.14.1", default-features = false, path = "../juniper"}
|
||||||
|
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
tokio = "0.1.8"
|
tokio = "0.1.8"
|
||||||
|
@ -25,6 +25,6 @@ pretty_env_logger = "0.2"
|
||||||
reqwest = "0.9"
|
reqwest = "0.9"
|
||||||
|
|
||||||
[dev-dependencies.juniper]
|
[dev-dependencies.juniper]
|
||||||
version = "0.14.0"
|
version = "0.14.1"
|
||||||
features = ["expose-test-schema", "serde_json"]
|
features = ["expose-test-schema", "serde_json"]
|
||||||
path = "../juniper"
|
path = "../juniper"
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
- Compatibility with the latest `juniper`.
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
||||||
|
# [[0.6.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.6.1)
|
||||||
|
|
||||||
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
||||||
# [[0.6.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.6.0)
|
# [[0.6.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.6.0)
|
||||||
|
|
||||||
- Compatibility with the latest `juniper`.
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "juniper_iron"
|
name = "juniper_iron"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
authors = [
|
authors = [
|
||||||
"Magnus Hallin <mhallin@fastmail.com>",
|
"Magnus Hallin <mhallin@fastmail.com>",
|
||||||
"Christoph Herzog <chris@theduke.at>",
|
"Christoph Herzog <chris@theduke.at>",
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
serde = { version = "1.0.2" }
|
serde = { version = "1.0.2" }
|
||||||
serde_json = { version = "1.0.2" }
|
serde_json = { version = "1.0.2" }
|
||||||
serde_derive = { version = "1.0.2" }
|
serde_derive = { version = "1.0.2" }
|
||||||
juniper = { version = "0.14.0", path = "../juniper" }
|
juniper = { version = "0.14.1", path = "../juniper" }
|
||||||
|
|
||||||
urlencoded = { version = ">= 0.5, < 0.7" }
|
urlencoded = { version = ">= 0.5, < 0.7" }
|
||||||
iron = ">= 0.5, < 0.7"
|
iron = ">= 0.5, < 0.7"
|
||||||
|
@ -29,6 +29,6 @@ url = "2"
|
||||||
percent-encoding = "2"
|
percent-encoding = "2"
|
||||||
|
|
||||||
[dev-dependencies.juniper]
|
[dev-dependencies.juniper]
|
||||||
version = "0.14.0"
|
version = "0.14.1"
|
||||||
features = ["expose-test-schema", "serde_json"]
|
features = ["expose-test-schema", "serde_json"]
|
||||||
path = "../juniper"
|
path = "../juniper"
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
- Compatibility with the latest `juniper`.
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
||||||
|
# [[0.5.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper_rocket-0.5.1)
|
||||||
|
|
||||||
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
||||||
# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_rocket-0.5.0)
|
# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_rocket-0.5.0)
|
||||||
|
|
||||||
- Compatibility with the latest `juniper`.
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "juniper_rocket"
|
name = "juniper_rocket"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
authors = [
|
authors = [
|
||||||
"Magnus Hallin <mhallin@fastmail.com>",
|
"Magnus Hallin <mhallin@fastmail.com>",
|
||||||
"Christoph Herzog <chris@theduke.at>",
|
"Christoph Herzog <chris@theduke.at>",
|
||||||
|
@ -18,13 +18,13 @@ async = [ "juniper/async" ]
|
||||||
serde = { version = "1.0.2" }
|
serde = { version = "1.0.2" }
|
||||||
serde_json = { version = "1.0.2" }
|
serde_json = { version = "1.0.2" }
|
||||||
serde_derive = { version = "1.0.2" }
|
serde_derive = { version = "1.0.2" }
|
||||||
juniper = { version = "0.14.0", default-features = false, path = "../juniper"}
|
juniper = { version = "0.14.1", default-features = false, path = "../juniper"}
|
||||||
|
|
||||||
futures03 = { version = "=0.3.0-alpha.19", 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" }
|
rocket = { git = "https://github.com/SergioBenitez/Rocket", branch = "async" }
|
||||||
tokio = "=0.2.0-alpha.6"
|
tokio = "=0.2.0-alpha.6"
|
||||||
|
|
||||||
[dev-dependencies.juniper]
|
[dev-dependencies.juniper]
|
||||||
version = "0.14.0"
|
version = "0.14.1"
|
||||||
features = ["expose-test-schema", "serde_json"]
|
features = ["expose-test-schema", "serde_json"]
|
||||||
path = "../juniper"
|
path = "../juniper"
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
- Compatibility with the latest `juniper`.
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
||||||
|
# [[0.5.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.5.1)
|
||||||
|
|
||||||
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
||||||
# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.5.0)
|
# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.5.0)
|
||||||
|
|
||||||
- Compatibility with the latest `juniper`.
|
- Compatibility with the latest `juniper`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "juniper_warp"
|
name = "juniper_warp"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
authors = ["Tom Houlé <tom@tomhoule.com>"]
|
authors = ["Tom Houlé <tom@tomhoule.com>"]
|
||||||
description = "Juniper GraphQL integration with Warp"
|
description = "Juniper GraphQL integration with Warp"
|
||||||
license = "BSD-2-Clause"
|
license = "BSD-2-Clause"
|
||||||
|
@ -13,7 +13,7 @@ async = [ "juniper/async", "futures03" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
warp = "0.1.8"
|
warp = "0.1.8"
|
||||||
juniper = { version = "0.14.0", path = "../juniper", default-features = false }
|
juniper = { version = "0.14.1", path = "../juniper", default-features = false }
|
||||||
serde_json = "1.0.24"
|
serde_json = "1.0.24"
|
||||||
serde_derive = "1.0.75"
|
serde_derive = "1.0.75"
|
||||||
failure = "0.1.2"
|
failure = "0.1.2"
|
||||||
|
@ -24,7 +24,7 @@ tokio-threadpool = "0.1.7"
|
||||||
futures03 = { version = "=0.3.0-alpha.19", optional = true, package = "futures-preview", features = ["compat"] }
|
futures03 = { version = "=0.3.0-alpha.19", optional = true, package = "futures-preview", features = ["compat"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
juniper = { version = "0.14.0", path = "../juniper", features = ["expose-test-schema", "serde_json"] }
|
juniper = { version = "0.14.1", path = "../juniper", features = ["expose-test-schema", "serde_json"] }
|
||||||
env_logger = "0.5.11"
|
env_logger = "0.5.11"
|
||||||
log = "0.4.3"
|
log = "0.4.3"
|
||||||
percent-encoding = "1.0"
|
percent-encoding = "1.0"
|
||||||
|
|
Loading…
Add table
Reference in a new issue