Make FieldResults in field resolvers optional :D
This commit is contained in:
parent
f3469dd270
commit
5caea1f908
20 changed files with 328 additions and 258 deletions
|
@ -132,7 +132,7 @@ as well.
|
|||
* [X] `graphql_input_object!` helper completely missing
|
||||
* [X] Add support for deprecating things
|
||||
* [X] Custom enum values and descriptions
|
||||
* [ ] Improved syntax for fields that can't fail resolution - make
|
||||
* [X] Improved syntax for fields that can't fail resolution - make
|
||||
`FieldResult<T>` optional maybe?
|
||||
* [ ] Investigate asynchronous execution - implementing it is not necessary, but
|
||||
at least look at what API changes will be needed for us to hook into
|
||||
|
|
|
@ -61,6 +61,23 @@ pub type FieldResult<T> = Result<T, String>;
|
|||
/// The result of resolving an unspecified field
|
||||
pub type ExecutionResult = Result<Value, String>;
|
||||
|
||||
/// Convert a value into a successful field result
|
||||
///
|
||||
/// Used by the helper macros to support both returning a naked value
|
||||
/// *and* a `FieldResult` from a field.
|
||||
pub trait IntoFieldResult<T>: Sized {
|
||||
/// Wrap `self` in a `Result`
|
||||
///
|
||||
/// The implementation of this should always be `Ok(self)`.
|
||||
fn into(self) -> FieldResult<T>;
|
||||
}
|
||||
|
||||
impl<T> IntoFieldResult<T> for FieldResult<T> {
|
||||
fn into(self) -> FieldResult<T> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, CtxT> Executor<'a, CtxT> {
|
||||
/// Resolve a single arbitrary value into an `ExecutionResult`
|
||||
pub fn resolve<T: GraphQLType<CtxT>>(&mut self, value: &T) -> ExecutionResult {
|
||||
|
@ -293,6 +310,17 @@ impl<CtxT> Registry<CtxT> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn field_convert<T: IntoFieldResult<I>, I>(&mut self, name: &str) -> Field where I: GraphQLType<CtxT> {
|
||||
Field {
|
||||
name: name.to_owned(),
|
||||
description: None,
|
||||
arguments: None,
|
||||
field_type: self.get_type::<I>(),
|
||||
deprecation_reason: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn field_inside_result<T>(&mut self, name: &str, _: FieldResult<T>) -> Field where T: GraphQLType<CtxT> {
|
||||
Field {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use executor::FieldResult;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
||||
|
@ -32,9 +31,9 @@ graphql_enum!(Sample as "SampleEnum" {
|
|||
|
||||
graphql_interface!(Interface: () as "SampleInterface" |&self| {
|
||||
description: "A sample interface"
|
||||
|
||||
field sample_enum() -> FieldResult<Sample> as "A sample field in the interface" {
|
||||
Ok(Sample::One)
|
||||
|
||||
field sample_enum() -> Sample as "A sample field in the interface" {
|
||||
Sample::One
|
||||
}
|
||||
|
||||
instance_resolvers: |&_| [
|
||||
|
@ -47,15 +46,15 @@ graphql_object!(Root: () as "Root" |&self| {
|
|||
|
||||
interfaces: [Interface]
|
||||
|
||||
field sample_enum() -> FieldResult<Sample> {
|
||||
Ok(Sample::One)
|
||||
field sample_enum() -> Sample {
|
||||
Sample::One
|
||||
}
|
||||
|
||||
field sample_scalar(
|
||||
first: i64 as "The first number",
|
||||
first: i64 as "The first number",
|
||||
second = 123: i64 as "The second number"
|
||||
) -> FieldResult<Scalar> as "A sample scalar field on the object" {
|
||||
Ok(Scalar(first + second))
|
||||
) -> Scalar as "A sample scalar field on the object" {
|
||||
Scalar(first + second)
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -121,7 +120,7 @@ fn enum_introspection() {
|
|||
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("SampleEnum")));
|
||||
assert_eq!(type_info.get("kind"), Some(&Value::string("ENUM")));
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("interfaces"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("possibleTypes"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("inputFields"), Some(&Value::null()));
|
||||
|
|
32
src/lib.rs
32
src/lib.rs
|
@ -28,8 +28,8 @@ existing object types as GraphQL objects:
|
|||
|
||||
```rust
|
||||
#[macro_use] extern crate juniper;
|
||||
use juniper::FieldResult;
|
||||
# use std::collections::HashMap;
|
||||
use juniper::FieldResult;
|
||||
|
||||
struct User { id: String, name: String, friend_ids: Vec<String> }
|
||||
struct QueryRoot;
|
||||
|
@ -42,15 +42,19 @@ struct Database { users: HashMap<String, User> }
|
|||
graphql_object!(User: Database as "User" |&self| {
|
||||
|
||||
// Expose a simple field as a GraphQL string.
|
||||
field id() -> &String {
|
||||
&self.id
|
||||
}
|
||||
|
||||
field name() -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
// FieldResult<T> is an alias for Result<T, String> - simply return
|
||||
// a string from this method and it will be correctly inserted into
|
||||
// the execution response.
|
||||
field id() -> FieldResult<&String> {
|
||||
Ok(&self.id)
|
||||
}
|
||||
|
||||
field name() -> FieldResult<&String> {
|
||||
Ok(&self.name)
|
||||
field secret() -> FieldResult<&String> {
|
||||
Err("Can't touch this".to_owned())
|
||||
}
|
||||
|
||||
// Field accessors can optionally take an "executor" as their first
|
||||
|
@ -59,10 +63,10 @@ graphql_object!(User: Database as "User" |&self| {
|
|||
//
|
||||
// In this example, the context is used to convert the friend_ids array
|
||||
// into actual User objects.
|
||||
field friends(&mut executor) -> FieldResult<Vec<&User>> {
|
||||
Ok(self.friend_ids.iter()
|
||||
field friends(&mut executor) -> Vec<&User> {
|
||||
self.friend_ids.iter()
|
||||
.filter_map(|id| executor.context().users.get(id))
|
||||
.collect())
|
||||
.collect()
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -71,8 +75,8 @@ graphql_object!(User: Database as "User" |&self| {
|
|||
graphql_object!(QueryRoot: Database as "Query" |&self| {
|
||||
|
||||
// Arguments work just like they do on functions.
|
||||
field user(&mut executor, id: String) -> FieldResult<Option<&User>> {
|
||||
Ok(executor.context().users.get(&id))
|
||||
field user(&mut executor, id: String) -> Option<&User> {
|
||||
executor.context().users.get(&id)
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -197,13 +201,13 @@ use rustc_serialize::json::{ToJson, Json};
|
|||
|
||||
use parser::{parse_document_source, ParseError, Spanning, SourcePosition};
|
||||
use validation::{RuleError, ValidatorContext, visit_all_rules};
|
||||
use executor::execute_validated_query;
|
||||
|
||||
pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection};
|
||||
pub use value::Value;
|
||||
pub use types::base::{Arguments, GraphQLType, TypeKind};
|
||||
pub use executor::{
|
||||
Executor, Registry, ExecutionResult, ExecutionError, FieldResult,
|
||||
execute_validated_query,
|
||||
Executor, Registry, ExecutionResult, ExecutionError, FieldResult, IntoFieldResult,
|
||||
};
|
||||
pub use types::scalars::ID;
|
||||
pub use schema::model::RootNode;
|
||||
|
|
|
@ -110,6 +110,12 @@ macro_rules! graphql_enum {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::IntoFieldResult<$name> for $name {
|
||||
fn into(self) -> $crate::FieldResult<$name> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// No more items to parse
|
||||
|
|
|
@ -77,7 +77,7 @@ macro_rules! __graphql__build_field_matches {
|
|||
$body
|
||||
};
|
||||
|
||||
return result.and_then(|r| $executorvar.resolve(&r))
|
||||
return ($crate::IntoFieldResult::into(result)).and_then(|r| $executorvar.resolve(&r))
|
||||
}
|
||||
)*
|
||||
panic!("Field {} not found on type {}", $fieldvar, $outname);
|
||||
|
|
|
@ -38,7 +38,6 @@ shared context to implement downcasts.
|
|||
|
||||
```rust
|
||||
# #[macro_use] extern crate juniper;
|
||||
# use juniper::FieldResult;
|
||||
# use std::collections::HashMap;
|
||||
struct Human { id: String }
|
||||
struct Droid { id: String }
|
||||
|
@ -60,16 +59,16 @@ impl Character for Droid {
|
|||
}
|
||||
|
||||
graphql_object!(Human: Database as "Human" |&self| {
|
||||
field id() -> FieldResult<&str> { Ok(&self.id) }
|
||||
field id() -> &str { &self.id }
|
||||
});
|
||||
|
||||
graphql_object!(Droid: Database as "Droid" |&self| {
|
||||
field id() -> FieldResult<&str> { Ok(&self.id) }
|
||||
field id() -> &str { &self.id }
|
||||
});
|
||||
|
||||
// You can introduce lifetimes or generic parameters by < > before the name.
|
||||
graphql_interface!(<'a> &'a Character: Database as "Character" |&self| {
|
||||
field id() -> FieldResult<&str> { Ok(self.id()) }
|
||||
field id() -> &str { self.id() }
|
||||
|
||||
instance_resolvers: |&context| [
|
||||
context.humans.get(self.id()),
|
||||
|
@ -97,9 +96,8 @@ macro_rules! graphql_interface {
|
|||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
$reg,
|
||||
$reg.field_inside_result(
|
||||
&$crate::to_snake_case(stringify!($name)),
|
||||
Err("dummy".to_owned()) as $t)
|
||||
$reg.field_convert::<$t, _>(
|
||||
&$crate::to_snake_case(stringify!($name)))
|
||||
.description($desc)
|
||||
.deprecated($reason),
|
||||
$args));
|
||||
|
@ -116,9 +114,8 @@ macro_rules! graphql_interface {
|
|||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
$reg,
|
||||
$reg.field_inside_result(
|
||||
&$crate::to_snake_case(stringify!($name)),
|
||||
Err("dummy".to_owned()) as $t)
|
||||
$reg.field_convert::<$t, _>(
|
||||
&$crate::to_snake_case(stringify!($name)))
|
||||
.deprecated($reason),
|
||||
$args));
|
||||
|
||||
|
@ -134,9 +131,8 @@ macro_rules! graphql_interface {
|
|||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
$reg,
|
||||
$reg.field_inside_result(
|
||||
&$crate::to_snake_case(stringify!($name)),
|
||||
Err("dummy".to_owned()) as $t)
|
||||
$reg.field_convert::<$t, _>(
|
||||
&$crate::to_snake_case(stringify!($name)))
|
||||
.description($desc),
|
||||
$args));
|
||||
|
||||
|
@ -152,9 +148,8 @@ macro_rules! graphql_interface {
|
|||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
$reg,
|
||||
$reg.field_inside_result(
|
||||
&$crate::to_snake_case(stringify!($name)),
|
||||
Err("dummy".to_owned()) as $t),
|
||||
$reg.field_convert::<$t, _>(
|
||||
&$crate::to_snake_case(stringify!($name))),
|
||||
$args));
|
||||
|
||||
graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*);
|
||||
|
|
|
@ -11,23 +11,22 @@ The simplest case exposes fields on a struct:
|
|||
|
||||
```rust
|
||||
# #[macro_use] extern crate juniper;
|
||||
# use juniper::FieldResult;
|
||||
struct User { id: String, name: String, group_ids: Vec<String> }
|
||||
|
||||
graphql_object!(User: () as "User" |&self| {
|
||||
field id() -> FieldResult<&String> {
|
||||
Ok(&self.id)
|
||||
field id() -> &String {
|
||||
&self.id
|
||||
}
|
||||
|
||||
field name() -> FieldResult<&String> {
|
||||
Ok(&self.name)
|
||||
field name() -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
// Field and argument names will be converted from snake case to camel case,
|
||||
// as is the common naming convention in GraphQL. The following field would
|
||||
// be named "memberOfGroup", and the argument "groupId".
|
||||
field member_of_group(group_id: String) -> FieldResult<bool> {
|
||||
Ok(self.group_ids.iter().any(|gid| gid == &group_id))
|
||||
field member_of_group(group_id: String) -> bool {
|
||||
self.group_ids.iter().any(|gid| gid == &group_id)
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -41,24 +40,23 @@ arguments:
|
|||
|
||||
```rust
|
||||
# #[macro_use] extern crate juniper;
|
||||
# use juniper::FieldResult;
|
||||
struct User { id: String, name: String, group_ids: Vec<String> }
|
||||
|
||||
graphql_object!(User: () as "User" |&self| {
|
||||
description: "A user in the database"
|
||||
|
||||
field id() -> FieldResult<&String> as "The user's unique identifier" {
|
||||
Ok(&self.id)
|
||||
field id() -> &String as "The user's unique identifier" {
|
||||
&self.id
|
||||
}
|
||||
|
||||
field name() -> FieldResult<&String> as "The user's name" {
|
||||
Ok(&self.name)
|
||||
field name() -> &String as "The user's name" {
|
||||
&self.name
|
||||
}
|
||||
|
||||
field member_of_group(
|
||||
group_id: String as "The group id you want to test membership against"
|
||||
) -> FieldResult<bool> as "Test if a user is member of a group" {
|
||||
Ok(self.group_ids.iter().any(|gid| gid == &group_id))
|
||||
) -> bool as "Test if a user is member of a group" {
|
||||
self.group_ids.iter().any(|gid| gid == &group_id)
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -72,26 +70,16 @@ generic parameters:
|
|||
|
||||
```rust
|
||||
# #[macro_use] extern crate juniper;
|
||||
# use juniper::FieldResult;
|
||||
trait SomeTrait { fn id(&self) -> &str; }
|
||||
|
||||
graphql_object!(<'a> &'a SomeTrait: () as "SomeTrait" |&self| {
|
||||
field id() -> FieldResult<&str> { Ok(self.id()) }
|
||||
field id() -> &str { self.id() }
|
||||
});
|
||||
|
||||
struct GenericType<T> { items: Vec<T> }
|
||||
|
||||
graphql_object!(<T> GenericType<T>: () as "GenericType" |&self| {
|
||||
field count() -> FieldResult<i64> { Ok(self.items.len() as i64) }
|
||||
});
|
||||
|
||||
struct SelfContained { name: String }
|
||||
|
||||
// If the type does not require access to a specific context, you can make it
|
||||
// generic on the context type. This statically ensures that the fields only
|
||||
// can access what's available from the type itself.
|
||||
graphql_object!(<Context> SelfContained: Context as "SelfContained" |&self| {
|
||||
field name() -> FieldResult<&String> { Ok(&self.name) }
|
||||
field count() -> i64 { self.items.len() as i64 }
|
||||
});
|
||||
|
||||
# fn main() { }
|
||||
|
@ -103,7 +91,6 @@ You can use the `interfaces` item to implement interfaces:
|
|||
|
||||
```rust
|
||||
# #[macro_use] extern crate juniper;
|
||||
# use juniper::FieldResult;
|
||||
trait Interface {
|
||||
fn id(&self) -> &str;
|
||||
fn as_implementor(&self) -> Option<Implementor>;
|
||||
|
@ -111,7 +98,7 @@ trait Interface {
|
|||
struct Implementor { id: String }
|
||||
|
||||
graphql_interface!(<'a> &'a Interface: () as "Interface" |&self| {
|
||||
field id() -> FieldResult<&str> { Ok(self.id()) }
|
||||
field id() -> &str { self.id() }
|
||||
|
||||
instance_resolvers: |&context| [
|
||||
self.as_implementor(),
|
||||
|
@ -119,7 +106,7 @@ graphql_interface!(<'a> &'a Interface: () as "Interface" |&self| {
|
|||
});
|
||||
|
||||
graphql_object!(Implementor: () as "Implementor" |&self| {
|
||||
field id() -> FieldResult<&str> { Ok(&self.id) }
|
||||
field id() -> &str { &self.id }
|
||||
|
||||
interfaces: [&Interface]
|
||||
});
|
||||
|
@ -194,8 +181,10 @@ need to have any connection, only what's exposed in the schema matters.
|
|||
### Fields
|
||||
|
||||
```text
|
||||
field name(args...) -> FieldResult<Type> { }
|
||||
field name(args...) -> FieldResult<Type> as "Field description" { }
|
||||
field name(args...) -> Type { }
|
||||
field name(args...) -> Type as "Field description" { }
|
||||
field deprecated "Reason" name(args...) -> Type { }
|
||||
field deprecated "Reason" name(args...) -> Type as "Field description" { }
|
||||
```
|
||||
|
||||
Defines a field on the object. The name is converted to camel case, e.g.
|
||||
|
@ -248,9 +237,8 @@ macro_rules! graphql_object {
|
|||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
$reg,
|
||||
$reg.field_inside_result(
|
||||
&$crate::to_snake_case(stringify!($name)),
|
||||
Err("dummy".to_owned()) as $t)
|
||||
$reg.field_convert::<$t, _>(
|
||||
&$crate::to_snake_case(stringify!($name)))
|
||||
.description($desc)
|
||||
.deprecated($reason),
|
||||
$args));
|
||||
|
@ -267,9 +255,8 @@ macro_rules! graphql_object {
|
|||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
$reg,
|
||||
$reg.field_inside_result(
|
||||
&$crate::to_snake_case(stringify!($name)),
|
||||
Err("dummy".to_owned()) as $t)
|
||||
$reg.field_convert::<$t, _>(
|
||||
&$crate::to_snake_case(stringify!($name)))
|
||||
.deprecated($reason),
|
||||
$args));
|
||||
|
||||
|
@ -285,9 +272,8 @@ macro_rules! graphql_object {
|
|||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
$reg,
|
||||
$reg.field_inside_result(
|
||||
&$crate::to_snake_case(stringify!($name)),
|
||||
Err("dummy".to_owned()) as $t)
|
||||
$reg.field_convert::<$t, _>(
|
||||
&$crate::to_snake_case(stringify!($name)))
|
||||
.description($desc),
|
||||
$args));
|
||||
|
||||
|
@ -303,9 +289,8 @@ macro_rules! graphql_object {
|
|||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
$reg,
|
||||
$reg.field_inside_result(
|
||||
&$crate::to_snake_case(stringify!($name)),
|
||||
Err("dummy".to_owned()) as $t),
|
||||
$reg.field_convert::<$t, _>(
|
||||
&$crate::to_snake_case(stringify!($name))),
|
||||
$args));
|
||||
|
||||
graphql_object!(@gather_object_meta, $reg, $acc, $descr, $ifaces, $( $rest )*);
|
||||
|
@ -407,6 +392,12 @@ macro_rules! graphql_object {
|
|||
$($items)*);
|
||||
}
|
||||
});
|
||||
|
||||
impl<$($lifetime)*> $crate::IntoFieldResult<$name> for $name {
|
||||
fn into(self) -> $crate::FieldResult<$name> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(
|
||||
|
|
|
@ -92,6 +92,12 @@ macro_rules! graphql_scalar {
|
|||
$fiv_body
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::IntoFieldResult<$name> for $name {
|
||||
fn into(self) -> $crate::FieldResult<$name> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// No more items to parse
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use executor::FieldResult;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
||||
|
@ -20,49 +19,49 @@ Syntax to validate:
|
|||
*/
|
||||
|
||||
graphql_object!(Root: () as "Root" |&self| {
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field exec_arg(&mut executor) -> FieldResult<i64> { Ok(0) }
|
||||
field exec_arg_and_more(&mut executor, arg: i64) -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
field exec_arg(&mut executor) -> i64 { 0 }
|
||||
field exec_arg_and_more(&mut executor, arg: i64) -> i64 { 0 }
|
||||
|
||||
field single_arg(arg: i64) -> FieldResult<i64> { Ok(0) }
|
||||
field single_arg(arg: i64) -> i64 { 0 }
|
||||
field multi_args(
|
||||
arg1: i64,
|
||||
arg2: i64
|
||||
) -> FieldResult<i64> { Ok(0) }
|
||||
) -> i64 { 0 }
|
||||
field multi_args_trailing_comma(
|
||||
arg1: i64,
|
||||
arg2: i64,
|
||||
) -> FieldResult<i64> { Ok(0) }
|
||||
) -> i64 { 0 }
|
||||
|
||||
field single_arg_descr(arg: i64 as "The arg") -> FieldResult<i64> { Ok(0) }
|
||||
field single_arg_descr(arg: i64 as "The arg") -> i64 { 0 }
|
||||
field multi_args_descr(
|
||||
arg1: i64 as "The first arg",
|
||||
arg2: i64 as "The second arg"
|
||||
) -> FieldResult<i64> { Ok(0) }
|
||||
) -> i64 { 0 }
|
||||
field multi_args_descr_trailing_comma(
|
||||
arg1: i64 as "The first arg",
|
||||
arg2: i64 as "The second arg",
|
||||
) -> FieldResult<i64> { Ok(0) }
|
||||
) -> i64 { 0 }
|
||||
|
||||
field arg_with_default(arg = 123: i64) -> FieldResult<i64> { Ok(0) }
|
||||
field arg_with_default(arg = 123: i64) -> i64 { 0 }
|
||||
field multi_args_with_default(
|
||||
arg1 = 123: i64,
|
||||
arg2 = 456: i64
|
||||
) -> FieldResult<i64> { Ok(0) }
|
||||
) -> i64 { 0 }
|
||||
field multi_args_with_default_trailing_comma(
|
||||
arg1 = 123: i64,
|
||||
arg2 = 456: i64,
|
||||
) -> FieldResult<i64> { Ok(0) }
|
||||
) -> i64 { 0 }
|
||||
|
||||
field arg_with_default_descr(arg = 123: i64 as "The arg") -> FieldResult<i64> { Ok(0) }
|
||||
field arg_with_default_descr(arg = 123: i64 as "The arg") -> i64 { 0 }
|
||||
field multi_args_with_default_descr(
|
||||
arg1 = 123: i64 as "The first arg",
|
||||
arg2 = 456: i64 as "The second arg"
|
||||
) -> FieldResult<i64> { Ok(0) }
|
||||
) -> i64 { 0 }
|
||||
field multi_args_with_default_trailing_comma_descr(
|
||||
arg1 = 123: i64 as "The first arg",
|
||||
arg2 = 456: i64 as "The second arg",
|
||||
) -> FieldResult<i64> { Ok(0) }
|
||||
) -> i64 { 0 }
|
||||
});
|
||||
|
||||
fn run_args_info_query<F>(field_name: &str, f: F)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use executor::FieldResult;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
||||
|
@ -59,12 +58,12 @@ graphql_enum!(EnumDeprecation {
|
|||
});
|
||||
|
||||
graphql_object!(Root: () as "Root" |&self| {
|
||||
field default_name() -> FieldResult<DefaultName> { Ok(DefaultName::Foo) }
|
||||
field named() -> FieldResult<Named> { Ok(Named::Foo) }
|
||||
field no_trailing_comma() -> FieldResult<NoTrailingComma> { Ok(NoTrailingComma::Foo) }
|
||||
field enum_description() -> FieldResult<EnumDescription> { Ok(EnumDescription::Foo) }
|
||||
field enum_value_description() -> FieldResult<EnumValueDescription> { Ok(EnumValueDescription::Foo) }
|
||||
field enum_deprecation() -> FieldResult<EnumDeprecation> { Ok(EnumDeprecation::Foo) }
|
||||
field default_name() -> DefaultName { DefaultName::Foo }
|
||||
field named() -> Named { Named::Foo }
|
||||
field no_trailing_comma() -> NoTrailingComma { NoTrailingComma::Foo }
|
||||
field enum_description() -> EnumDescription { EnumDescription::Foo }
|
||||
field enum_value_description() -> EnumValueDescription { EnumValueDescription::Foo }
|
||||
field enum_deprecation() -> EnumDeprecation { EnumDeprecation::Foo }
|
||||
});
|
||||
|
||||
fn run_type_info_query<F>(doc: &str, f: F) where F: Fn((&HashMap<String, Value>, &Vec<Value>)) -> () {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use executor::FieldResult;
|
||||
use value::Value;
|
||||
use ast::InputValue;
|
||||
use schema::model::RootNode;
|
||||
|
@ -19,29 +18,29 @@ Syntax to validate:
|
|||
*/
|
||||
|
||||
graphql_object!(Root: () as "Root" |&self| {
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
|
||||
field description() -> FieldResult<i64> as "Field description" { Ok(0) }
|
||||
field description() -> i64 as "Field description" { 0 }
|
||||
|
||||
field deprecated "Deprecation reason"
|
||||
deprecated() -> FieldResult<i64> { Ok(0) }
|
||||
deprecated() -> i64 { 0 }
|
||||
|
||||
field deprecated "Deprecation reason"
|
||||
deprecated_descr() -> FieldResult<i64> as "Field description" { Ok(0) }
|
||||
deprecated_descr() -> i64 as "Field description" { 0 }
|
||||
|
||||
interfaces: [Interface]
|
||||
});
|
||||
|
||||
graphql_interface!(Interface: () as "Interface" |&self| {
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
|
||||
field description() -> FieldResult<i64> as "Field description" { Ok(0) }
|
||||
field description() -> i64 as "Field description" { 0 }
|
||||
|
||||
field deprecated "Deprecation reason"
|
||||
deprecated() -> FieldResult<i64> { Ok(0) }
|
||||
deprecated() -> i64 { 0 }
|
||||
|
||||
field deprecated "Deprecation reason"
|
||||
deprecated_descr() -> FieldResult<i64> as "Field description" { Ok(0) }
|
||||
deprecated_descr() -> i64 as "Field description" { 0 }
|
||||
|
||||
instance_resolvers: |&_| [
|
||||
Some(Root {}),
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use ast::{InputValue, FromInputValue};
|
||||
use executor::FieldResult;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
||||
|
@ -57,8 +56,8 @@ graphql_object!(Root: () as "Root" |&self| {
|
|||
a4: Named,
|
||||
a5: Description,
|
||||
a6: FieldDescription
|
||||
) -> FieldResult<i64> {
|
||||
Ok(0)
|
||||
) -> i64 {
|
||||
0
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use ast::InputValue;
|
||||
use executor::FieldResult;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
||||
|
@ -20,8 +20,11 @@ struct Interface;
|
|||
|
||||
struct DefaultName;
|
||||
|
||||
struct WithLifetime;
|
||||
struct WithGenerics;
|
||||
#[allow(dead_code)]
|
||||
struct WithLifetime<'a> { data: PhantomData<&'a i64> }
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct WithGenerics<T> { data: T }
|
||||
|
||||
struct DescriptionFirst;
|
||||
struct FieldsFirst;
|
||||
|
@ -33,20 +36,21 @@ struct CommasOnMeta;
|
|||
struct Root;
|
||||
|
||||
graphql_object!(DefaultName: () |&self| {
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
});
|
||||
|
||||
|
||||
graphql_object!(<'a> &'a WithLifetime: () as "WithLifetime" |&self| {
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
graphql_object!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| {
|
||||
field simple() -> i64 { 0 }
|
||||
});
|
||||
|
||||
graphql_object!(<CtxT> WithGenerics: CtxT as "WithGenerics" |&self| {
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
graphql_object!(<T> WithGenerics<T>: () as "WithGenerics" |&self| {
|
||||
field simple() -> i64 { 0 }
|
||||
});
|
||||
|
||||
|
||||
graphql_interface!(Interface: () as "Interface" |&self| {
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
|
||||
instance_resolvers: |_| [
|
||||
Some(DescriptionFirst {}),
|
||||
|
@ -56,13 +60,13 @@ graphql_interface!(Interface: () as "Interface" |&self| {
|
|||
graphql_object!(DescriptionFirst: () as "DescriptionFirst" |&self| {
|
||||
description: "A description"
|
||||
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
|
||||
interfaces: [Interface]
|
||||
});
|
||||
|
||||
graphql_object!(FieldsFirst: () as "FieldsFirst" |&self| {
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
|
||||
description: "A description"
|
||||
|
||||
|
@ -72,7 +76,7 @@ graphql_object!(FieldsFirst: () as "FieldsFirst" |&self| {
|
|||
graphql_object!(InterfacesFirst: () as "InterfacesFirst" |&self| {
|
||||
interfaces: [Interface]
|
||||
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
|
||||
description: "A description"
|
||||
});
|
||||
|
@ -80,7 +84,7 @@ graphql_object!(InterfacesFirst: () as "InterfacesFirst" |&self| {
|
|||
graphql_object!(CommasWithTrailing: () as "CommasWithTrailing" |&self| {
|
||||
interfaces: [Interface],
|
||||
|
||||
field simple() -> FieldResult<i64> { Ok(0) },
|
||||
field simple() -> i64 { 0 },
|
||||
|
||||
description: "A description",
|
||||
});
|
||||
|
@ -90,21 +94,21 @@ graphql_object!(CommasOnMeta: () as "CommasOnMeta" |&self| {
|
|||
interfaces: [Interface],
|
||||
description: "A description",
|
||||
|
||||
field simple() -> FieldResult<i64> { Ok(0) }
|
||||
field simple() -> i64 { 0 }
|
||||
});
|
||||
|
||||
graphql_object!(Root: () as "Root" |&self| {
|
||||
field default_name() -> FieldResult<DefaultName> { Ok(DefaultName {}) }
|
||||
graphql_object!(<'a> Root: () as "Root" |&self| {
|
||||
field default_name() -> DefaultName { DefaultName {} }
|
||||
|
||||
field with_lifetime() -> FieldResult<&WithLifetime> { Err("Nope".to_owned()) }
|
||||
field with_generics() -> FieldResult<WithGenerics> { Ok(WithGenerics {}) }
|
||||
field with_lifetime() -> WithLifetime<'a> { WithLifetime { data: PhantomData } }
|
||||
field with_generics() -> WithGenerics<i64> { WithGenerics { data: 123 } }
|
||||
|
||||
field description_first() -> FieldResult<DescriptionFirst> { Ok(DescriptionFirst {}) }
|
||||
field fields_first() -> FieldResult<FieldsFirst> { Ok(FieldsFirst {}) }
|
||||
field interfaces_first() -> FieldResult<InterfacesFirst> { Ok(InterfacesFirst {}) }
|
||||
field description_first() -> DescriptionFirst { DescriptionFirst {} }
|
||||
field fields_first() -> FieldsFirst { FieldsFirst {} }
|
||||
field interfaces_first() -> InterfacesFirst { InterfacesFirst {} }
|
||||
|
||||
field commas_with_trailing() -> FieldResult<CommasWithTrailing> { Ok(CommasWithTrailing {}) }
|
||||
field commas_on_meta() -> FieldResult<CommasOnMeta> { Ok(CommasOnMeta {}) }
|
||||
field commas_with_trailing() -> CommasWithTrailing { CommasWithTrailing {} }
|
||||
field commas_on_meta() -> CommasOnMeta { CommasOnMeta {} }
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use executor::FieldResult;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
||||
|
@ -63,10 +62,10 @@ graphql_scalar!(ScalarDescription {
|
|||
});
|
||||
|
||||
graphql_object!(Root: () as "Root" |&self| {
|
||||
field default_name() -> FieldResult<DefaultName> { Ok(DefaultName(0)) }
|
||||
field other_order() -> FieldResult<OtherOrder> { Ok(OtherOrder(0)) }
|
||||
field named() -> FieldResult<Named> { Ok(Named(0)) }
|
||||
field scalar_description() -> FieldResult<ScalarDescription> { Ok(ScalarDescription(0)) }
|
||||
field default_name() -> DefaultName { DefaultName(0) }
|
||||
field other_order() -> OtherOrder { OtherOrder(0) }
|
||||
field named() -> Named { Named(0) }
|
||||
field scalar_description() -> ScalarDescription { ScalarDescription(0) }
|
||||
});
|
||||
|
||||
fn run_type_info_query<F>(doc: &str, f: F) where F: Fn(&HashMap<String, Value>) -> () {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustc_serialize::json::ToJson;
|
||||
|
||||
use types::base::{GraphQLType, Arguments, TypeKind};
|
||||
use executor::{Executor, Registry, FieldResult, ExecutionResult};
|
||||
use executor::{Executor, Registry, ExecutionResult};
|
||||
|
||||
use schema::meta::{MetaType, ObjectMeta, EnumMeta, InputObjectMeta, UnionMeta, InterfaceMeta,
|
||||
Field, Argument, EnumValue};
|
||||
|
@ -32,48 +32,48 @@ impl<CtxT, QueryT, MutationT> GraphQLType<CtxT> for RootNode<CtxT, QueryT, Mutat
|
|||
}
|
||||
|
||||
graphql_object!(SchemaType: SchemaType as "__Schema" |&self| {
|
||||
field types() -> FieldResult<Vec<TypeType>> {
|
||||
Ok(self.type_list())
|
||||
field types() -> Vec<TypeType> {
|
||||
self.type_list()
|
||||
}
|
||||
|
||||
field query_type() -> FieldResult<TypeType> {
|
||||
Ok(self.query_type())
|
||||
field query_type() -> TypeType {
|
||||
self.query_type()
|
||||
}
|
||||
|
||||
field mutation_type() -> FieldResult<Option<TypeType>> {
|
||||
Ok(self.mutation_type())
|
||||
field mutation_type() -> Option<TypeType> {
|
||||
self.mutation_type()
|
||||
}
|
||||
|
||||
field directives() -> FieldResult<Vec<&DirectiveType>> {
|
||||
Ok(self.directive_list())
|
||||
field directives() -> Vec<&DirectiveType> {
|
||||
self.directive_list()
|
||||
}
|
||||
});
|
||||
|
||||
graphql_object!(<'a> TypeType<'a>: SchemaType as "__Type" |&self| {
|
||||
field name() -> FieldResult<Option<&str>> {
|
||||
Ok(match *self {
|
||||
field name() -> Option<&str> {
|
||||
match *self {
|
||||
TypeType::Concrete(t) => t.name(),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field description() -> FieldResult<Option<&String>> {
|
||||
Ok(match *self {
|
||||
field description() -> Option<&String> {
|
||||
match *self {
|
||||
TypeType::Concrete(t) => t.description(),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field kind() -> FieldResult<TypeKind> {
|
||||
Ok(match *self {
|
||||
field kind() -> TypeKind {
|
||||
match *self {
|
||||
TypeType::Concrete(t) => t.type_kind(),
|
||||
TypeType::List(_) => TypeKind::List,
|
||||
TypeType::NonNull(_) => TypeKind::NonNull,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field fields(include_deprecated = false: bool) -> FieldResult<Option<Vec<&Field>>> {
|
||||
Ok(match *self {
|
||||
field fields(include_deprecated = false: bool) -> Option<Vec<&Field>> {
|
||||
match *self {
|
||||
TypeType::Concrete(&MetaType::Interface(InterfaceMeta { ref fields, .. })) |
|
||||
TypeType::Concrete(&MetaType::Object(ObjectMeta { ref fields, .. })) =>
|
||||
Some(fields
|
||||
|
@ -81,26 +81,26 @@ graphql_object!(<'a> TypeType<'a>: SchemaType as "__Type" |&self| {
|
|||
.filter(|f| include_deprecated || f.deprecation_reason.is_none())
|
||||
.collect()),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field of_type() -> FieldResult<Option<&TypeType>> {
|
||||
Ok(match *self {
|
||||
field of_type() -> Option<&TypeType> {
|
||||
match *self {
|
||||
TypeType::Concrete(_) => None,
|
||||
TypeType::List(ref l) | TypeType::NonNull(ref l) => Some(l),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field input_fields() -> FieldResult<Option<&Vec<Argument>>> {
|
||||
Ok(match *self {
|
||||
field input_fields() -> Option<&Vec<Argument>> {
|
||||
match *self {
|
||||
TypeType::Concrete(&MetaType::InputObject(InputObjectMeta { ref input_fields, .. })) =>
|
||||
Some(input_fields),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field interfaces(&mut executor) -> FieldResult<Option<Vec<TypeType>>> {
|
||||
Ok(match *self {
|
||||
field interfaces(&mut executor) -> Option<Vec<TypeType>> {
|
||||
match *self {
|
||||
TypeType::Concrete(&MetaType::Object(ObjectMeta { ref interface_names, .. })) => {
|
||||
let schema = executor.context();
|
||||
Some(interface_names
|
||||
|
@ -109,12 +109,12 @@ graphql_object!(<'a> TypeType<'a>: SchemaType as "__Type" |&self| {
|
|||
.collect())
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field possible_types(&mut executor) -> FieldResult<Option<Vec<TypeType>>> {
|
||||
field possible_types(&mut executor) -> Option<Vec<TypeType>> {
|
||||
let schema = executor.context();
|
||||
Ok(match *self {
|
||||
match *self {
|
||||
TypeType::Concrete(&MetaType::Union(UnionMeta { ref of_type_names, .. })) => {
|
||||
Some(of_type_names
|
||||
.iter()
|
||||
|
@ -134,80 +134,80 @@ graphql_object!(<'a> TypeType<'a>: SchemaType as "__Type" |&self| {
|
|||
.collect())
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field enum_values(include_deprecated = false: bool) -> FieldResult<Option<Vec<&EnumValue>>> {
|
||||
Ok(match *self {
|
||||
field enum_values(include_deprecated = false: bool) -> Option<Vec<&EnumValue>> {
|
||||
match *self {
|
||||
TypeType::Concrete(&MetaType::Enum(EnumMeta { ref values, .. })) =>
|
||||
Some(values
|
||||
.iter()
|
||||
.filter(|f| include_deprecated || f.deprecation_reason.is_none())
|
||||
.collect()),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
graphql_object!(Field: SchemaType as "__Field" |&self| {
|
||||
field name() -> FieldResult<&String> {
|
||||
Ok(&self.name)
|
||||
field name() -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
field description() -> FieldResult<&Option<String>> {
|
||||
Ok(&self.description)
|
||||
field description() -> &Option<String> {
|
||||
&self.description
|
||||
}
|
||||
|
||||
field args() -> FieldResult<Vec<&Argument>> {
|
||||
Ok(self.arguments.as_ref().map_or_else(|| Vec::new(), |v| v.iter().collect()))
|
||||
field args() -> Vec<&Argument> {
|
||||
self.arguments.as_ref().map_or_else(|| Vec::new(), |v| v.iter().collect())
|
||||
}
|
||||
|
||||
field type(&mut executor) -> FieldResult<TypeType> {
|
||||
Ok(executor.context().make_type(&self.field_type))
|
||||
field type(&mut executor) -> TypeType {
|
||||
executor.context().make_type(&self.field_type)
|
||||
}
|
||||
|
||||
field is_deprecated() -> FieldResult<bool> {
|
||||
Ok(self.deprecation_reason.is_some())
|
||||
field is_deprecated() -> bool {
|
||||
self.deprecation_reason.is_some()
|
||||
}
|
||||
|
||||
field deprecation_reason() -> FieldResult<&Option<String>> {
|
||||
Ok(&self.deprecation_reason)
|
||||
field deprecation_reason() -> &Option<String> {
|
||||
&self.deprecation_reason
|
||||
}
|
||||
});
|
||||
|
||||
graphql_object!(Argument: SchemaType as "__InputValue" |&self| {
|
||||
field name() -> FieldResult<&String> {
|
||||
Ok(&self.name)
|
||||
field name() -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
field description() -> FieldResult<&Option<String>> {
|
||||
Ok(&self.description)
|
||||
field description() -> &Option<String> {
|
||||
&self.description
|
||||
}
|
||||
|
||||
field type(&mut executor) -> FieldResult<TypeType> {
|
||||
Ok(executor.context().make_type(&self.arg_type))
|
||||
field type(&mut executor) -> TypeType {
|
||||
executor.context().make_type(&self.arg_type)
|
||||
}
|
||||
|
||||
field default_value() -> FieldResult<Option<String>> {
|
||||
Ok(self.default_value.as_ref().map(|v| v.to_json().to_string()))
|
||||
field default_value() -> Option<String> {
|
||||
self.default_value.as_ref().map(|v| v.to_json().to_string())
|
||||
}
|
||||
});
|
||||
|
||||
graphql_object!(EnumValue: SchemaType as "__EnumValue" |&self| {
|
||||
field name() -> FieldResult<&String> {
|
||||
Ok(&self.name)
|
||||
field name() -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
field description() -> FieldResult<&Option<String>> {
|
||||
Ok(&self.description)
|
||||
field description() -> &Option<String> {
|
||||
&self.description
|
||||
}
|
||||
|
||||
field is_deprecated() -> FieldResult<bool> {
|
||||
Ok(self.deprecation_reason.is_some())
|
||||
field is_deprecated() -> bool {
|
||||
self.deprecation_reason.is_some()
|
||||
}
|
||||
|
||||
field deprecation_reason() -> FieldResult<&Option<String>> {
|
||||
Ok(&self.deprecation_reason)
|
||||
field deprecation_reason() -> &Option<String> {
|
||||
&self.deprecation_reason
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -224,20 +224,20 @@ graphql_enum!(TypeKind as "__TypeKind" {
|
|||
|
||||
|
||||
graphql_object!(DirectiveType: SchemaType as "__Directive" |&self| {
|
||||
field name() -> FieldResult<&String> {
|
||||
Ok(&self.name)
|
||||
field name() -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
field description() -> FieldResult<&Option<String>> {
|
||||
Ok(&self.description)
|
||||
field description() -> &Option<String> {
|
||||
&self.description
|
||||
}
|
||||
|
||||
field locations() -> FieldResult<&Vec<DirectiveLocation>> {
|
||||
Ok(&self.locations)
|
||||
field locations() -> &Vec<DirectiveLocation> {
|
||||
&self.locations
|
||||
}
|
||||
|
||||
field args() -> FieldResult<&Vec<Argument>> {
|
||||
Ok(&self.arguments)
|
||||
field args() -> &Vec<Argument> {
|
||||
&self.arguments
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use executor::FieldResult;
|
||||
use tests::model::{Character, Human, Droid, Database, Episode};
|
||||
|
||||
graphql_enum!(Episode {
|
||||
|
@ -10,21 +9,21 @@ graphql_enum!(Episode {
|
|||
graphql_interface!(<'a> &'a Character: Database as "Character" |&self| {
|
||||
description: "A character in the Star Wars Trilogy"
|
||||
|
||||
field id() -> FieldResult<&str> as "The id of the character" {
|
||||
Ok(self.id())
|
||||
field id() -> &str as "The id of the character" {
|
||||
self.id()
|
||||
}
|
||||
|
||||
field name() -> FieldResult<Option<&str>> as "The name of the character" {
|
||||
Ok(Some(self.name()))
|
||||
field name() -> Option<&str> as "The name of the character" {
|
||||
Some(self.name())
|
||||
}
|
||||
|
||||
field friends(&mut executor) -> FieldResult<Vec<&Character>>
|
||||
field friends(&mut executor) -> Vec<&Character>
|
||||
as "The friends of the character" {
|
||||
Ok(executor.context().get_friends(self.as_character()))
|
||||
executor.context().get_friends(self.as_character())
|
||||
}
|
||||
|
||||
field appears_in() -> FieldResult<&[Episode]> as "Which movies they appear in" {
|
||||
Ok(self.appears_in())
|
||||
field appears_in() -> &[Episode] as "Which movies they appear in" {
|
||||
self.appears_in()
|
||||
}
|
||||
|
||||
instance_resolvers: |&context| [
|
||||
|
@ -38,25 +37,25 @@ graphql_object!(<'a> &'a Human: Database as "Human" |&self| {
|
|||
|
||||
interfaces: [&Character]
|
||||
|
||||
field id() -> FieldResult<&str> as "The id of the human"{
|
||||
Ok(self.id())
|
||||
field id() -> &str as "The id of the human"{
|
||||
self.id()
|
||||
}
|
||||
|
||||
field name() -> FieldResult<Option<&str>> as "The name of the human" {
|
||||
Ok(Some(self.name()))
|
||||
field name() -> Option<&str> as "The name of the human" {
|
||||
Some(self.name())
|
||||
}
|
||||
|
||||
field friends(&mut executor) -> FieldResult<Vec<&Character>>
|
||||
field friends(&mut executor) -> Vec<&Character>
|
||||
as "The friends of the human" {
|
||||
Ok(executor.context().get_friends(self.as_character()))
|
||||
executor.context().get_friends(self.as_character())
|
||||
}
|
||||
|
||||
field appears_in() -> FieldResult<&[Episode]> as "Which movies they appear in" {
|
||||
Ok(self.appears_in())
|
||||
field appears_in() -> &[Episode] as "Which movies they appear in" {
|
||||
self.appears_in()
|
||||
}
|
||||
|
||||
field home_planet() -> FieldResult<&Option<String>> as "The home planet of the human" {
|
||||
Ok(self.home_planet())
|
||||
field home_planet() -> &Option<String> as "The home planet of the human" {
|
||||
self.home_planet()
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -65,25 +64,25 @@ graphql_object!(<'a> &'a Droid: Database as "Droid" |&self| {
|
|||
|
||||
interfaces: [&Character]
|
||||
|
||||
field id() -> FieldResult<&str> as "The id of the droid" {
|
||||
Ok(self.id())
|
||||
field id() -> &str as "The id of the droid" {
|
||||
self.id()
|
||||
}
|
||||
|
||||
field name() -> FieldResult<Option<&str>> as "The name of the droid" {
|
||||
Ok(Some(self.name()))
|
||||
field name() -> Option<&str> as "The name of the droid" {
|
||||
Some(self.name())
|
||||
}
|
||||
|
||||
field friends(&mut executor) -> FieldResult<Vec<&Character>>
|
||||
field friends(&mut executor) -> Vec<&Character>
|
||||
as "The friends of the droid" {
|
||||
Ok(executor.context().get_friends(self.as_character()))
|
||||
executor.context().get_friends(self.as_character())
|
||||
}
|
||||
|
||||
field appears_in() -> FieldResult<&[Episode]> as "Which movies they appear in" {
|
||||
Ok(self.appears_in())
|
||||
field appears_in() -> &[Episode] as "Which movies they appear in" {
|
||||
self.appears_in()
|
||||
}
|
||||
|
||||
field primary_function() -> FieldResult<&Option<String>> as "The primary function of the droid" {
|
||||
Ok(self.primary_function())
|
||||
field primary_function() -> &Option<String> as "The primary function of the droid" {
|
||||
self.primary_function()
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -93,21 +92,21 @@ graphql_object!(Database: Database as "Query" |&self| {
|
|||
|
||||
field human(
|
||||
id: String as "id of the human"
|
||||
) -> FieldResult<Option<&Human>> {
|
||||
Ok(self.get_human(&id))
|
||||
) -> Option<&Human> {
|
||||
self.get_human(&id)
|
||||
}
|
||||
|
||||
field droid(
|
||||
id: String as "id of the droid"
|
||||
) -> FieldResult<Option<&Droid>> {
|
||||
Ok(self.get_droid(&id))
|
||||
) -> Option<&Droid> {
|
||||
self.get_droid(&id)
|
||||
}
|
||||
|
||||
field hero(
|
||||
episode: Option<Episode> as
|
||||
"If omitted, returns the hero of the whole saga. If provided, returns \
|
||||
the hero of that particular episode"
|
||||
) -> FieldResult<Option<&Character>> {
|
||||
Ok(Some(self.get_hero(episode).as_character()))
|
||||
) -> Option<&Character> {
|
||||
Some(self.get_hero(episode).as_character())
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@ use ast::{InputValue, ToInputValue, FromInputValue, Selection};
|
|||
use value::Value;
|
||||
use schema::meta::MetaType;
|
||||
|
||||
use executor::{Executor, Registry};
|
||||
use executor::{Executor, Registry, IntoFieldResult, FieldResult};
|
||||
use types::base::{GraphQLType};
|
||||
|
||||
impl<T, CtxT> GraphQLType<CtxT> for Option<T> where T: GraphQLType<CtxT> {
|
||||
|
@ -43,6 +43,12 @@ impl<T> ToInputValue for Option<T> where T: ToInputValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoFieldResult<Option<T>> for Option<T> {
|
||||
fn into(self) -> FieldResult<Option<T>> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T, CtxT> GraphQLType<CtxT> for Vec<T> where T: GraphQLType<CtxT> {
|
||||
fn name() -> Option<&'static str> {
|
||||
|
@ -84,6 +90,12 @@ impl<T> ToInputValue for Vec<T> where T: ToInputValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoFieldResult<Vec<T>> for Vec<T> {
|
||||
fn into(self) -> FieldResult<Vec<T>> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a, T, CtxT> GraphQLType<CtxT> for &'a [T] where T: GraphQLType<CtxT> {
|
||||
fn name() -> Option<&'static str> {
|
||||
|
@ -106,3 +118,9 @@ impl<'a, T> ToInputValue for &'a [T] where T: ToInputValue {
|
|||
InputValue::list(self.iter().map(|v| v.to()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoFieldResult<&'a [T]> for &'a [T] {
|
||||
fn into(self) -> FieldResult<&'a [T]> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use ast::{Selection, InputValue, ToInputValue, FromInputValue};
|
|||
use value::Value;
|
||||
|
||||
use schema::meta::MetaType;
|
||||
use executor::{Executor, Registry, ExecutionResult};
|
||||
use executor::{Executor, Registry, ExecutionResult, IntoFieldResult, FieldResult};
|
||||
use types::base::{Arguments, GraphQLType};
|
||||
|
||||
impl<T, CtxT> GraphQLType<CtxT> for Box<T> where T: GraphQLType<CtxT> {
|
||||
|
@ -43,6 +43,12 @@ impl<T> ToInputValue for Box<T> where T: ToInputValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoFieldResult<Box<T>> for Box<T> {
|
||||
fn into(self) -> FieldResult<Box<T>> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, CtxT> GraphQLType<CtxT> for &'a T where T: GraphQLType<CtxT> {
|
||||
fn name() -> Option<&'static str> {
|
||||
T::name()
|
||||
|
@ -71,3 +77,9 @@ impl<'a, T> ToInputValue for &'a T where T: ToInputValue {
|
|||
(**self).to()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoFieldResult<&'a T> for &'a T {
|
||||
fn into(self) -> FieldResult<&'a T> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use value::Value;
|
|||
|
||||
use schema::meta::MetaType;
|
||||
|
||||
use executor::{Executor, Registry};
|
||||
use executor::{Executor, Registry, FieldResult, IntoFieldResult};
|
||||
use types::base::GraphQLType;
|
||||
|
||||
/// An ID as defined by the GraphQL specification
|
||||
|
@ -60,6 +60,13 @@ impl<'a> ToInputValue for &'a str {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoFieldResult<&'a str> for &'a str {
|
||||
fn into(self) -> FieldResult<&'a str> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
graphql_scalar!(bool as "Boolean" {
|
||||
resolve(&self) -> Value {
|
||||
|
@ -119,3 +126,9 @@ impl FromInputValue for () {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoFieldResult<()> for () {
|
||||
fn into(self) -> FieldResult<()> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue