This commit is contained in:
nWacky 2019-11-04 16:55:36 +03:00
parent 00dd1dc391
commit e3c12e31fc
No known key found for this signature in database
GPG key ID: 22EF2C62F6F79FD0
9 changed files with 122 additions and 132 deletions

View file

@ -2,13 +2,11 @@
//! This example demonstrates async/await usage with warp.
//! NOTE: this uses tokio 0.1 , not the alpha tokio 0.2.
use juniper::{EmptyMutation, RootNode, FieldError};
use juniper::{EmptyMutation, FieldError, RootNode};
use warp::{http::Response, Filter};
#[derive(Clone)]
struct Context {
}
struct Context {}
impl juniper::Context for Context {}
#[derive(juniper::GraphQLEnum, Clone, Copy)]
@ -43,23 +41,24 @@ impl User {
}
}
struct Query;
struct Query;
#[juniper::object(Context = Context)]
impl Query {
async fn users() -> Vec<User> {
vec![
User{
id: 1,
kind: UserKind::Admin,
name: "user1".into(),
},
]
vec![User {
id: 1,
kind: UserKind::Admin,
name: "user1".into(),
}]
}
/// Fetch a URL and return the response body text.
async fn request(url: String) -> Result<String, FieldError> {
use futures::{ compat::{Stream01CompatExt, Future01CompatExt}, stream::TryStreamExt};
use futures::{
compat::{Future01CompatExt, Stream01CompatExt},
stream::TryStreamExt,
};
let res = reqwest::r#async::Client::new()
.get(&url)
@ -95,7 +94,7 @@ fn main() {
log::info!("Listening on 127.0.0.1:8080");
let state = warp::any().map(move || Context{} );
let state = warp::any().map(move || Context {});
let graphql_filter = juniper_warp::make_graphql_filter_async(schema(), state.boxed());
warp::serve(

View file

@ -73,12 +73,12 @@ impl Root {
0
}
fn attr_arg_descr(#[doc = "The arg"] arg: i32) -> i32 { 0 }
fn attr_arg_descr_collapse(
#[doc = "The arg"]
#[doc = "and more details"]
arg: i32,
) -> i32 { 0 }
fn attr_arg_descr(arg: i32) -> i32 {
0
}
fn attr_arg_descr_collapse(arg: i32) -> i32 {
0
}
#[graphql(arguments(arg(default = 123,),))]
fn arg_with_default(arg: i32) -> i32 {
@ -558,71 +558,71 @@ fn introspect_field_multi_args_descr_trailing_comma() {
});
}
#[test]
fn introspect_field_attr_arg_descr() {
run_args_info_query("attrArgDescr", |args| {
assert_eq!(args.len(), 1);
#[test]
fn introspect_field_attr_arg_descr() {
run_args_info_query("attrArgDescr", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(
vec![
("name", Value::scalar("arg")),
("description", Value::scalar("The arg")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::scalar("Int"))].into_iter().collect(),
),
),
]
.into_iter()
.collect(),
),
),
]
.into_iter()
.collect(),
)));
});
}
assert!(args.contains(&Value::object(
vec![
("name", Value::scalar("arg")),
("description", Value::scalar("The arg")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::scalar("Int"))].into_iter().collect(),
),
),
]
.into_iter()
.collect(),
),
),
]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_field_attr_arg_descr_collapse() {
run_args_info_query("attrArgDescrCollapse", |args| {
assert_eq!(args.len(), 1);
#[test]
fn introspect_field_attr_arg_descr_collapse() {
run_args_info_query("attrArgDescrCollapse", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(
vec![
("name", Value::scalar("arg")),
("description", Value::scalar("The arg\nand more details")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::scalar("Int"))].into_iter().collect(),
),
),
]
.into_iter()
.collect(),
),
),
]
.into_iter()
.collect(),
)));
});
}
assert!(args.contains(&Value::object(
vec![
("name", Value::scalar("arg")),
("description", Value::scalar("The arg\nand more details")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::scalar("Int"))].into_iter().collect(),
),
),
]
.into_iter()
.collect(),
),
),
]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_field_arg_with_default() {

View file

@ -98,13 +98,12 @@ where
) -> ExecutionResult<S> {
use futures::future::{ready, FutureExt};
match field_name {
"__schema" | "__type" => {
self.resolve_field(info, field_name, arguments, executor)
"__schema" | "__type" => self.resolve_field(info, field_name, arguments, executor),
_ => {
self.query_type
.resolve_field_async(info, field_name, arguments, executor)
.await
}
_ => self
.query_type
.resolve_field_async(info, field_name, arguments, executor)
.await,
}
}
}

View file

@ -1,8 +1,8 @@
use async_trait::async_trait;
use crate::{
ast::{Directive, FromInputValue, InputValue, Selection},
value::{Object, ScalarRefValue, ScalarValue, Value},
};
use async_trait::async_trait;
use crate::{
executor::{ExecutionResult, Executor},
@ -239,12 +239,14 @@ where
);
if let Some(ref type_condition) = fragment.type_condition {
let sub_result = instance.resolve_into_type_async(
info,
type_condition.item,
Some(&fragment.selection_set[..]),
&sub_exec,
).await;
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 {

View file

@ -153,13 +153,8 @@ where
arguments: &'b Arguments<'b, S>,
executor: &'b Executor<'b, <Self as crate::GraphQLType<S>>::Context, S>,
) -> ExecutionResult<S> {
crate::GraphQLTypeAsync::resolve_field_async(
&**self,
info,
field_name,
arguments,
executor
).await
crate::GraphQLTypeAsync::resolve_field_async(&**self, info, field_name, arguments, executor)
.await
}
async fn resolve_async<'a>(
@ -168,12 +163,7 @@ where
selection_set: Option<&'a [Selection<'a, S>]>,
executor: &'a Executor<'a, <Self as crate::GraphQLType<S>>::Context, S>,
) -> Value<S> {
crate::GraphQLTypeAsync::resolve_async(
&**self,
info,
selection_set,
executor
).await
crate::GraphQLTypeAsync::resolve_async(&**self, info, selection_set, executor).await
}
}

View file

@ -41,18 +41,15 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
}
}
let name =
if let Some(name) = impl_attrs.name.as_ref(){
let name = if let Some(name) = impl_attrs.name.as_ref() {
name.to_string()
}
else {
} else {
if let Some(ident) = util::name_of_type(&*_impl.self_ty) {
ident.to_string()
} else {
panic!("Could not determine a name for the object type: specify one with #[juniper::object(name = \"SomeName\")");
}
};
panic!("Could not determine a name for the object type: specify one with #[juniper::object(name = \"SomeName\")");
}
};
let target_type = *_impl.self_ty.clone();

View file

@ -1,7 +1,7 @@
use proc_macro::TokenStream;
use proc_macro_error::MacroError;
use quote::{quote};
use quote::quote;
use syn::spanned::Spanned;
use crate::util;
@ -39,7 +39,7 @@ impl syn::parse::Parse for ResolveBody {
body.parse::<syn::token::Match>()?;
body.parse::<syn::token::SelfValue>()?;
let match_body;
let match_body;
syn::braced!( match_body in body );
let mut variants = Vec::new();
@ -67,7 +67,6 @@ pub fn impl_union(
attrs: TokenStream,
body: TokenStream,
) -> Result<TokenStream, MacroError> {
// We are re-using the object attributes since they are almost the same.
let attrs = syn::parse::<util::ObjectAttributes>(attrs)?;
@ -76,7 +75,8 @@ pub fn impl_union(
if item.items.len() != 1 {
return Err(MacroError::new(
item.span(),
"Invalid impl body: expected one method with signature: fn resolve(&self) { ... }".to_string(),
"Invalid impl body: expected one method with signature: fn resolve(&self) { ... }"
.to_string(),
));
}
@ -92,7 +92,7 @@ pub fn impl_union(
"Expected a path ending in a simple type identifier".to_string(),
)
})?;
let name = attrs.name.unwrap_or_else(|| ty_ident.to_string());
let name = attrs.name.unwrap_or_else(|| ty_ident.to_string());
let juniper = util::juniper_path(is_internal);
@ -130,7 +130,9 @@ pub fn impl_union(
.scalar
.as_ref()
.map(|s| quote!( #s ))
.unwrap_or_else(|| { quote! { #juniper::DefaultScalarValue } });
.unwrap_or_else(|| {
quote! { #juniper::DefaultScalarValue }
});
let mut generics = item.generics.clone();
if attrs.scalar.is_some() {
@ -139,10 +141,12 @@ pub fn impl_union(
// compatible with ScalarValueRef.
// This is done to prevent the user from having to specify this
// manually.
let where_clause = generics.where_clause.get_or_insert(syn::parse_quote!(where));
where_clause.predicates.push(
syn::parse_quote!(for<'__b> &'__b #scalar: #juniper::ScalarRefValue<'__b>),
);
let where_clause = generics
.where_clause
.get_or_insert(syn::parse_quote!(where));
where_clause
.predicates
.push(syn::parse_quote!(for<'__b> &'__b #scalar: #juniper::ScalarRefValue<'__b>));
}
let (impl_generics, _, where_clause) = generics.split_for_impl();
@ -151,10 +155,13 @@ pub fn impl_union(
Some(value) => quote!( .description( #value ) ),
None => quote!(),
};
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! {
impl #impl_generics #juniper::GraphQLType<#scalar> for #ty #where_clause
impl #impl_generics #juniper::GraphQLType<#scalar> for #ty #where_clause
{
type Context = #context;
type TypeInfo = ();

View file

@ -389,4 +389,3 @@ pub fn union_internal(attrs: TokenStream, body: TokenStream) -> TokenStream {
};
output
}