Merge branch 'master' of https://github.com/graphql-rust/juniper into graphql-rust-master
This commit is contained in:
commit
934fcbb2bd
89 changed files with 3414 additions and 2542 deletions
|
@ -6,3 +6,17 @@
|
|||
**Note:** while this is not a Rust breaking change, if you relied on the serialization format (perhaps by storing serialized data in a database or making asumptions in your client code written in another language) it could be a breaking change for your application.
|
||||
|
||||
[#151](https://github.com/graphql-rust/juniper/pull/151)
|
||||
|
||||
* The `GraphQLObject`, `GraphQLInputObject`, and `GraphQLEnum` custom derives will reject
|
||||
invalid [names](http://facebook.github.io/graphql/October2016/#Name) at compile time.
|
||||
|
||||
[#170](https://github.com/graphql-rust/juniper/pull/170)
|
||||
|
||||
* Large integers (> signed 32bit) are now deserialized as floats. Previously,
|
||||
they produced the "integer out of range" error. For languages that do not
|
||||
have distinction between integer and floating point types (including
|
||||
javascript), this means large floating point values which do not have
|
||||
fractional part could not be decoded (because they are represented without
|
||||
a decimal part `.0`).
|
||||
|
||||
[#179](https://github.com/graphql-rust/juniper/pull/179)
|
|
@ -42,7 +42,7 @@ serde_derive = {version="1.0.2" }
|
|||
chrono = { version = "0.4.0", optional = true }
|
||||
serde_json = { version="1.0.2", optional = true }
|
||||
url = { version = "1.5.1", optional = true }
|
||||
uuid = { version = "0.5.1", optional = true }
|
||||
uuid = { version = "> 0.4, < 0.7", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
bencher = "0.1.2"
|
||||
|
|
|
@ -4,8 +4,8 @@ extern crate juniper;
|
|||
|
||||
use bencher::Bencher;
|
||||
|
||||
use juniper::{execute, EmptyMutation, RootNode, Variables};
|
||||
use juniper::tests::model::Database;
|
||||
use juniper::{execute, EmptyMutation, RootNode, Variables};
|
||||
|
||||
fn query_type_name(b: &mut Bencher) {
|
||||
let database = Database::new();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::fmt;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use std::vec;
|
||||
use std::slice;
|
||||
use std::vec;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
|
@ -432,25 +432,25 @@ impl fmt::Display for InputValue {
|
|||
InputValue::Enum(ref v) => write!(f, "{}", v),
|
||||
InputValue::Variable(ref v) => write!(f, "${}", v),
|
||||
InputValue::List(ref v) => {
|
||||
try!(write!(f, "["));
|
||||
write!(f, "[")?;
|
||||
|
||||
for (i, spanning) in v.iter().enumerate() {
|
||||
try!(spanning.item.fmt(f));
|
||||
spanning.item.fmt(f)?;
|
||||
if i < v.len() - 1 {
|
||||
try!(write!(f, ", "));
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
|
||||
write!(f, "]")
|
||||
}
|
||||
InputValue::Object(ref o) => {
|
||||
try!(write!(f, "{{"));
|
||||
write!(f, "{{")?;
|
||||
|
||||
for (i, &(ref k, ref v)) in o.iter().enumerate() {
|
||||
try!(write!(f, "{}: ", k.item));
|
||||
try!(v.item.fmt(f));
|
||||
write!(f, "{}: ", k.item)?;
|
||||
v.item.fmt(f)?;
|
||||
if i < o.len() - 1 {
|
||||
try!(write!(f, ", "));
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1077
juniper/src/executor/look_ahead.rs
Normal file
1077
juniper/src/executor/look_ahead.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,16 +1,16 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::fmt::Display;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use fnv::FnvHashMap;
|
||||
|
||||
use GraphQLError;
|
||||
use ast::{Definition, Document, Fragment, FromInputValue, InputValue, OperationType, Selection,
|
||||
ToInputValue, Type};
|
||||
use value::Value;
|
||||
use GraphQLError;
|
||||
use parser::SourcePosition;
|
||||
use value::Value;
|
||||
|
||||
use schema::meta::{Argument, EnumMeta, EnumValue, Field, InputObjectMeta, InterfaceMeta, ListMeta,
|
||||
MetaType, NullableMeta, ObjectMeta, PlaceholderMeta, ScalarMeta, UnionMeta};
|
||||
|
@ -19,6 +19,10 @@ use schema::model::{RootNode, SchemaType, TypeType};
|
|||
use types::base::GraphQLType;
|
||||
use types::name::Name;
|
||||
|
||||
mod look_ahead;
|
||||
|
||||
pub use self::look_ahead::{Applies, LookAheadArgument, LookAheadSelection, LookAheadValue, LookAheadMethods, ChildSelection, ConcreteLookAheadSelection};
|
||||
|
||||
/// A type registry used to build schemas
|
||||
///
|
||||
/// The registry gathers metadata for all types in a schema. It provides
|
||||
|
@ -46,6 +50,7 @@ where
|
|||
fragments: &'a HashMap<&'a str, &'a Fragment<'a>>,
|
||||
variables: &'a Variables,
|
||||
current_selection_set: Option<&'a [Selection<'a>]>,
|
||||
parent_selection_set: Option<&'a [Selection<'a>]>,
|
||||
current_type: TypeType<'a>,
|
||||
schema: &'a SchemaType<'a>,
|
||||
context: &'a CtxT,
|
||||
|
@ -220,7 +225,8 @@ impl<'a, T: GraphQLType, C> IntoResolvable<'a, T, C> for FieldResult<(&'a T::Con
|
|||
}
|
||||
|
||||
impl<'a, T: GraphQLType, C> IntoResolvable<'a, Option<T>, C>
|
||||
for FieldResult<Option<(&'a T::Context, T)>> {
|
||||
for FieldResult<Option<(&'a T::Context, T)>>
|
||||
{
|
||||
fn into(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, Option<T>)>> {
|
||||
self.map(|o| o.map(|(ctx, v)| (ctx, Some(v))))
|
||||
}
|
||||
|
@ -229,20 +235,20 @@ impl<'a, T: GraphQLType, C> IntoResolvable<'a, Option<T>, C>
|
|||
/// Conversion trait for context types
|
||||
///
|
||||
/// Used to support different context types for different parts of an
|
||||
/// application. By making each GraphQL type only aware of as much
|
||||
/// application. By making each `GraphQL` type only aware of as much
|
||||
/// context as it needs to, isolation and robustness can be
|
||||
/// improved. Implement this trait if you have contexts that can
|
||||
/// generally be converted between each other.
|
||||
///
|
||||
/// The empty tuple `()` can be converted into from any context type,
|
||||
/// making it suitable for GraphQL that don't need _any_ context to
|
||||
/// making it suitable for `GraphQL` that don't need _any_ context to
|
||||
/// work, e.g. scalars or enums.
|
||||
pub trait FromContext<T> {
|
||||
/// Perform the conversion
|
||||
fn from(value: &T) -> &Self;
|
||||
}
|
||||
|
||||
/// Marker trait for types that can act as context objects for GraphQL types.
|
||||
/// Marker trait for types that can act as context objects for `GraphQL` types.
|
||||
pub trait Context {}
|
||||
|
||||
impl<'a, C: Context> Context for &'a C {}
|
||||
|
@ -313,6 +319,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
|
|||
fragments: self.fragments,
|
||||
variables: self.variables,
|
||||
current_selection_set: self.current_selection_set,
|
||||
parent_selection_set: self.parent_selection_set,
|
||||
current_type: self.current_type.clone(),
|
||||
schema: self.schema,
|
||||
context: ctx,
|
||||
|
@ -333,6 +340,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
|
|||
fragments: self.fragments,
|
||||
variables: self.variables,
|
||||
current_selection_set: selection_set,
|
||||
parent_selection_set: self.current_selection_set,
|
||||
current_type: self.schema.make_type(
|
||||
&self.current_type
|
||||
.innermost_concrete()
|
||||
|
@ -357,6 +365,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
|
|||
fragments: self.fragments,
|
||||
variables: self.variables,
|
||||
current_selection_set: selection_set,
|
||||
parent_selection_set: self.current_selection_set,
|
||||
current_type: match type_name {
|
||||
Some(type_name) => self.schema.type_by_name(type_name).expect("Type not found"),
|
||||
None => self.current_type.clone(),
|
||||
|
@ -420,6 +429,26 @@ impl<'a, CtxT> Executor<'a, CtxT> {
|
|||
error: error,
|
||||
});
|
||||
}
|
||||
|
||||
/// Construct a lookahead selection for the current selection
|
||||
///
|
||||
/// This allows to see the whole selection and preform operations
|
||||
/// affecting the childs
|
||||
pub fn look_ahead(&'a self) -> LookAheadSelection<'a> {
|
||||
self.parent_selection_set.map(|p| {
|
||||
LookAheadSelection::build_from_selection(&p[0], self.variables, self.fragments)
|
||||
}).unwrap_or_else(||{
|
||||
LookAheadSelection{
|
||||
name: self.current_type.innermost_concrete().name().unwrap_or(""),
|
||||
alias: None,
|
||||
arguments: Vec::new(),
|
||||
children: self.current_selection_set.map(|s| s.iter().map(|s| ChildSelection {
|
||||
inner: LookAheadSelection::build_from_selection(s, self.variables, self.fragments),
|
||||
applies_for: Applies::All
|
||||
}).collect()).unwrap_or_else(Vec::new)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FieldPath<'a> {
|
||||
|
@ -547,6 +576,7 @@ where
|
|||
.collect(),
|
||||
variables: final_vars,
|
||||
current_selection_set: Some(&op.item.selection_set[..]),
|
||||
parent_selection_set: None,
|
||||
current_type: root_type,
|
||||
schema: &root_node.schema,
|
||||
context: context,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use indexmap::IndexMap;
|
||||
|
||||
use value::Value;
|
||||
use executor::Variables;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct TestType;
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use indexmap::IndexMap;
|
||||
|
||||
use value::Value;
|
||||
use ast::InputValue;
|
||||
use executor::Variables;
|
||||
use schema::model::RootNode;
|
||||
use GraphQLError::ValidationError;
|
||||
use validation::RuleError;
|
||||
use parser::SourcePosition;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use validation::RuleError;
|
||||
use value::Value;
|
||||
use GraphQLError::ValidationError;
|
||||
|
||||
#[derive(GraphQLEnum, Debug)]
|
||||
#[graphql(_internal)]
|
||||
|
@ -77,12 +77,10 @@ fn does_not_accept_string_literals() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Invalid value for argument "color", expected type "Color!""#,
|
||||
&[SourcePosition::new(18, 0, 18)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Invalid value for argument "color", expected type "Color!""#,
|
||||
&[SourcePosition::new(18, 0, 18)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -112,12 +110,10 @@ fn does_not_accept_incorrect_enum_name_in_variables() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -134,11 +130,9 @@ fn does_not_accept_incorrect_type_in_variables() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$color" got invalid value. Expected "Color", found not a string or enum."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
mod field_execution {
|
||||
use value::Value;
|
||||
use ast::InputValue;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct DataType;
|
||||
struct DeepDataType;
|
||||
|
@ -128,9 +128,9 @@ mod field_execution {
|
|||
}
|
||||
|
||||
mod merge_parallel_fragments {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct Type;
|
||||
|
||||
|
@ -198,9 +198,9 @@ mod merge_parallel_fragments {
|
|||
}
|
||||
|
||||
mod merge_parallel_inline_fragments {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct Type;
|
||||
struct Other;
|
||||
|
@ -270,38 +270,34 @@ mod merge_parallel_inline_fragments {
|
|||
("b", Value::string("Banana")),
|
||||
(
|
||||
"deeper",
|
||||
Value::list(
|
||||
vec![
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"deepest",
|
||||
Value::object(
|
||||
vec![
|
||||
("b", Value::string("Banana")),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter().collect()
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"deepest",
|
||||
Value::object(
|
||||
vec![
|
||||
("b", Value::string("Banana")),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter().collect()
|
||||
),
|
||||
]
|
||||
),
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![(
|
||||
"deepest",
|
||||
Value::object(
|
||||
vec![
|
||||
("b", Value::string("Banana")),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![(
|
||||
"deepest",
|
||||
Value::object(
|
||||
vec![
|
||||
("b", Value::string("Banana")),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter()
|
||||
|
@ -317,10 +313,10 @@ mod merge_parallel_inline_fragments {
|
|||
}
|
||||
|
||||
mod threads_context_correctly {
|
||||
use value::Value;
|
||||
use types::scalars::EmptyMutation;
|
||||
use schema::model::RootNode;
|
||||
use executor::Context;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct Schema;
|
||||
|
||||
|
@ -369,11 +365,11 @@ mod threads_context_correctly {
|
|||
mod dynamic_context_switching {
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use value::Value;
|
||||
use types::scalars::EmptyMutation;
|
||||
use schema::model::RootNode;
|
||||
use parser::SourcePosition;
|
||||
use executor::{Context, ExecutionError, FieldError, FieldResult};
|
||||
use parser::SourcePosition;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct Schema;
|
||||
|
||||
|
@ -509,16 +505,14 @@ mod dynamic_context_switching {
|
|||
assert_eq!(
|
||||
result,
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"first",
|
||||
Value::object(
|
||||
vec![("value", Value::string("First value"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"first",
|
||||
Value::object(
|
||||
vec![("value", Value::string("First value"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
|
@ -557,13 +551,11 @@ mod dynamic_context_switching {
|
|||
|
||||
assert_eq!(
|
||||
errs,
|
||||
vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(25, 2, 12),
|
||||
&["missing"],
|
||||
FieldError::new("Could not find key 2", Value::null()),
|
||||
),
|
||||
]
|
||||
vec![ExecutionError::new(
|
||||
SourcePosition::new(25, 2, 12),
|
||||
&["missing"],
|
||||
FieldError::new("Could not find key 2", Value::null()),
|
||||
)]
|
||||
);
|
||||
|
||||
println!("Result: {:?}", result);
|
||||
|
@ -606,13 +598,11 @@ mod dynamic_context_switching {
|
|||
|
||||
assert_eq!(
|
||||
errs,
|
||||
[
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(123, 4, 12),
|
||||
&["tooLarge"],
|
||||
FieldError::new("Key too large: 200", Value::null()),
|
||||
),
|
||||
]
|
||||
[ExecutionError::new(
|
||||
SourcePosition::new(123, 4, 12),
|
||||
&["tooLarge"],
|
||||
FieldError::new("Key too large: 200", Value::null()),
|
||||
)]
|
||||
);
|
||||
|
||||
println!("Result: {:?}", result);
|
||||
|
@ -671,16 +661,14 @@ mod dynamic_context_switching {
|
|||
assert_eq!(
|
||||
result,
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"first",
|
||||
Value::object(
|
||||
vec![("value", Value::string("First value"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"first",
|
||||
Value::object(
|
||||
vec![("value", Value::string("First value"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
|
@ -688,11 +676,11 @@ mod dynamic_context_switching {
|
|||
}
|
||||
|
||||
mod propagates_errors_to_nullable_fields {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use executor::{ExecutionError, FieldError, FieldResult};
|
||||
use parser::SourcePosition;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct Schema;
|
||||
struct Inner;
|
||||
|
@ -728,13 +716,11 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
errs,
|
||||
vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(10, 0, 10),
|
||||
&["inner", "nullableErrorField"],
|
||||
FieldError::new("Error for nullableErrorField", Value::null()),
|
||||
),
|
||||
]
|
||||
vec![ExecutionError::new(
|
||||
SourcePosition::new(10, 0, 10),
|
||||
&["inner", "nullableErrorField"],
|
||||
FieldError::new("Error for nullableErrorField", Value::null()),
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -753,13 +739,11 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
errs,
|
||||
vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(10, 0, 10),
|
||||
&["inner", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]
|
||||
vec![ExecutionError::new(
|
||||
SourcePosition::new(10, 0, 10),
|
||||
&["inner", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -781,13 +765,11 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
errs,
|
||||
vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(26, 0, 26),
|
||||
&["inner", "nullableField", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]
|
||||
vec![ExecutionError::new(
|
||||
SourcePosition::new(26, 0, 26),
|
||||
&["inner", "nullableField", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -806,13 +788,11 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
errs,
|
||||
vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(29, 0, 29),
|
||||
&["inner", "nonNullableField", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]
|
||||
vec![ExecutionError::new(
|
||||
SourcePosition::new(29, 0, 29),
|
||||
&["inner", "nonNullableField", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -834,13 +814,11 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
errs,
|
||||
vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(29, 0, 29),
|
||||
&["inner", "nonNullableField", "nullableErrorField"],
|
||||
FieldError::new("Error for nullableErrorField", Value::null()),
|
||||
),
|
||||
]
|
||||
vec![ExecutionError::new(
|
||||
SourcePosition::new(29, 0, 29),
|
||||
&["inner", "nonNullableField", "nullableErrorField"],
|
||||
FieldError::new("Error for nullableErrorField", Value::null()),
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -859,13 +837,11 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
errs,
|
||||
vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(11, 0, 11),
|
||||
&["inners", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]
|
||||
vec![ExecutionError::new(
|
||||
SourcePosition::new(11, 0, 11),
|
||||
&["inners", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -919,9 +895,9 @@ mod propagates_errors_to_nullable_fields {
|
|||
}
|
||||
|
||||
mod named_operations {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
use GraphQLError;
|
||||
|
||||
struct Schema;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
mod interface {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
trait Pet {
|
||||
fn name(&self) -> &str;
|
||||
|
@ -116,27 +116,25 @@ mod interface {
|
|||
assert_eq!(
|
||||
result,
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"pets",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"pets",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
)].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
|
@ -144,9 +142,9 @@ mod interface {
|
|||
}
|
||||
|
||||
mod union {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
trait Pet {
|
||||
fn as_dog(&self) -> Option<&Dog> {
|
||||
|
@ -249,29 +247,27 @@ mod union {
|
|||
assert_eq!(
|
||||
result,
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"pets",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("__typename", Value::string("Dog")),
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("__typename", Value::string("Cat")),
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"pets",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("__typename", Value::string("Dog")),
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("__typename", Value::string("Cat")),
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
)].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use indexmap::IndexMap;
|
||||
|
||||
use executor::Variables;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
/*
|
||||
|
||||
|
@ -48,15 +48,19 @@ enum EnumDescription {
|
|||
#[derive(GraphQLEnum)]
|
||||
#[graphql(_internal)]
|
||||
enum EnumValueDescription {
|
||||
#[graphql(description = "The FOO value")] Foo,
|
||||
#[graphql(description = "The BAR value")] Bar,
|
||||
#[graphql(description = "The FOO value")]
|
||||
Foo,
|
||||
#[graphql(description = "The BAR value")]
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[derive(GraphQLEnum)]
|
||||
#[graphql(_internal)]
|
||||
enum EnumDeprecation {
|
||||
#[graphql(deprecated = "Please don't use FOO any more")] Foo,
|
||||
#[graphql(description = "The BAR value", deprecated = "Please don't use BAR any more")] Bar,
|
||||
#[graphql(deprecated = "Please don't use FOO any more")]
|
||||
Foo,
|
||||
#[graphql(description = "The BAR value", deprecated = "Please don't use BAR any more")]
|
||||
Bar,
|
||||
}
|
||||
|
||||
struct Root;
|
||||
|
@ -131,7 +135,7 @@ fn default_name_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -143,7 +147,7 @@ fn default_name_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -180,7 +184,7 @@ fn named_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -192,7 +196,7 @@ fn named_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -232,7 +236,7 @@ fn no_trailing_comma_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -244,7 +248,7 @@ fn no_trailing_comma_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -287,7 +291,7 @@ fn enum_description_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -299,7 +303,7 @@ fn enum_description_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -339,7 +343,7 @@ fn enum_value_description_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -351,7 +355,7 @@ fn enum_value_description_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -394,7 +398,7 @@ fn enum_deprecation_introspection() {
|
|||
Value::string("Please don't use FOO any more"),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -409,7 +413,7 @@ fn enum_deprecation_introspection() {
|
|||
Value::string("Please don't use BAR any more"),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
|
|
@ -2,9 +2,9 @@ use indexmap::IndexMap;
|
|||
|
||||
use ast::{FromInputValue, InputValue};
|
||||
use executor::Variables;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct Root;
|
||||
|
||||
|
@ -53,8 +53,11 @@ pub struct PublicWithDescription {
|
|||
}
|
||||
|
||||
#[derive(GraphQLInputObject, Debug)]
|
||||
#[graphql(name = "APublicNamedInputObjectWithDescription",
|
||||
description = "Description for the input object", _internal)]
|
||||
#[graphql(
|
||||
name = "APublicNamedInputObjectWithDescription",
|
||||
description = "Description for the input object",
|
||||
_internal
|
||||
)]
|
||||
pub struct NamedPublicWithDescription {
|
||||
field_one: String,
|
||||
}
|
||||
|
@ -68,15 +71,19 @@ pub struct NamedPublic {
|
|||
#[derive(GraphQLInputObject, Debug)]
|
||||
#[graphql(_internal)]
|
||||
struct FieldDescription {
|
||||
#[graphql(description = "The first field")] field_one: String,
|
||||
#[graphql(description = "The second field")] field_two: String,
|
||||
#[graphql(description = "The first field")]
|
||||
field_one: String,
|
||||
#[graphql(description = "The second field")]
|
||||
field_two: String,
|
||||
}
|
||||
|
||||
#[derive(GraphQLInputObject, Debug)]
|
||||
#[graphql(_internal)]
|
||||
struct FieldWithDefaults {
|
||||
#[graphql(default = "123")] field_one: i32,
|
||||
#[graphql(default = "456", description = "The second field")] field_two: i32,
|
||||
#[graphql(default = "123")]
|
||||
field_one: i32,
|
||||
#[graphql(default = "456", description = "The second field")]
|
||||
field_two: i32,
|
||||
}
|
||||
|
||||
graphql_object!(Root: () |&self| {
|
||||
|
@ -162,22 +169,20 @@ fn default_name_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -189,22 +194,20 @@ fn default_name_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -268,22 +271,20 @@ fn no_trailing_comma_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -295,22 +296,20 @@ fn no_trailing_comma_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -351,22 +350,20 @@ fn derive_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -423,22 +420,20 @@ fn named_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -482,22 +477,20 @@ fn description_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -541,22 +534,20 @@ fn field_description_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -568,22 +559,20 @@ fn field_description_introspection() {
|
|||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -624,7 +613,7 @@ fn field_with_defaults_introspection() {
|
|||
),
|
||||
("defaultValue", Value::string("123")),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -638,7 +627,7 @@ fn field_with_defaults_introspection() {
|
|||
),
|
||||
("defaultValue", Value::string("456")),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
mod input_object;
|
||||
mod enums;
|
||||
mod input_object;
|
||||
|
||||
// This asserts that the input objects defined public actually became public
|
||||
#[allow(unused_imports)]
|
||||
use self::input_object::{NamedPublic, NamedPublicWithDescription};
|
||||
|
||||
use executor::Variables;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
#[derive(GraphQLEnum)]
|
||||
#[graphql(name = "SampleEnum", _internal)]
|
||||
|
@ -155,7 +155,7 @@ fn enum_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -167,7 +167,7 @@ fn enum_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ fn interface_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
}
|
||||
|
@ -366,13 +366,11 @@ fn object_introspection() {
|
|||
);
|
||||
assert_eq!(
|
||||
type_info.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![("name", Value::string("SampleInterface"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![("name", Value::string("SampleInterface"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
assert_eq!(type_info.get("enumValues"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("inputFields"), Some(&Value::null()));
|
||||
|
@ -418,7 +416,7 @@ fn object_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -506,7 +504,7 @@ fn object_introspection() {
|
|||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
mod introspection;
|
||||
mod variables;
|
||||
mod enums;
|
||||
mod directives;
|
||||
mod enums;
|
||||
mod executor;
|
||||
mod interfaces_unions;
|
||||
mod introspection;
|
||||
mod variables;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use indexmap::IndexMap;
|
||||
|
||||
use value::Value;
|
||||
use ast::InputValue;
|
||||
use executor::Variables;
|
||||
use schema::model::RootNode;
|
||||
use GraphQLError::ValidationError;
|
||||
use validation::RuleError;
|
||||
use parser::SourcePosition;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use validation::RuleError;
|
||||
use value::Value;
|
||||
use GraphQLError::ValidationError;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TestComplexScalar;
|
||||
|
@ -56,7 +56,8 @@ struct ExampleInputObject {
|
|||
#[derive(GraphQLInputObject, Debug)]
|
||||
#[graphql(_internal)]
|
||||
struct InputWithDefaults {
|
||||
#[graphql(default = "123")] a: i32,
|
||||
#[graphql(default = "123")]
|
||||
a: i32,
|
||||
}
|
||||
|
||||
graphql_object!(TestType: () |&self| {
|
||||
|
@ -177,19 +178,17 @@ fn inline_runs_from_input_value_on_scalar() {
|
|||
fn variable_complex_input() {
|
||||
run_variable_query(
|
||||
r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::list(vec![InputValue::string("bar")])),
|
||||
("c", InputValue::string("baz")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::list(vec![InputValue::string("bar")])),
|
||||
("c", InputValue::string("baz")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(
|
||||
|
@ -203,19 +202,17 @@ fn variable_complex_input() {
|
|||
fn variable_parse_single_value_to_list() {
|
||||
run_variable_query(
|
||||
r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::string("bar")),
|
||||
("c", InputValue::string("baz")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::string("bar")),
|
||||
("c", InputValue::string("baz")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(
|
||||
|
@ -229,18 +226,16 @@ fn variable_parse_single_value_to_list() {
|
|||
fn variable_runs_from_input_value_on_scalar() {
|
||||
run_variable_query(
|
||||
r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("c", InputValue::string("baz")),
|
||||
("d", InputValue::string("SerializedValue")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("c", InputValue::string("baz")),
|
||||
("d", InputValue::string("SerializedValue")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(
|
||||
|
@ -255,31 +250,27 @@ fn variable_error_on_nested_non_null() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#;
|
||||
let vars = vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::string("bar")),
|
||||
("c", InputValue::null()),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
let vars = vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::string("bar")),
|
||||
("c", InputValue::null()),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect();
|
||||
|
||||
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
|
||||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$input" got invalid value. In field "c": Expected "String!", found null."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -307,30 +298,26 @@ fn variable_error_on_omit_non_null() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#;
|
||||
let vars = vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::string("bar")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
let vars = vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::string("bar")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect();
|
||||
|
||||
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
|
||||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$input" got invalid value. In field "c": Expected "String!", found null."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -340,22 +327,16 @@ fn variable_multiple_errors_with_nesting() {
|
|||
|
||||
let query =
|
||||
r#"query q($input: TestNestedInputObject) { fieldWithNestedObjectInput(input: $input) }"#;
|
||||
let vars = vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
(
|
||||
"na",
|
||||
InputValue::object(
|
||||
vec![("a", InputValue::string("foo"))].into_iter().collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
let vars = vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![(
|
||||
"na",
|
||||
InputValue::object(vec![("a", InputValue::string("foo"))].into_iter().collect()),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect();
|
||||
|
||||
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
|
||||
|
@ -377,32 +358,28 @@ fn variable_error_on_additional_field() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#;
|
||||
let vars = vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::string("bar")),
|
||||
("c", InputValue::string("baz")),
|
||||
("extra", InputValue::string("dog")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
let vars = vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::object(
|
||||
vec![
|
||||
("a", InputValue::string("foo")),
|
||||
("b", InputValue::string("bar")),
|
||||
("c", InputValue::string("baz")),
|
||||
("extra", InputValue::string("dog")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect();
|
||||
|
||||
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
|
||||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$input" got invalid value. In field "extra": Unknown field."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$input" got invalid value. In field "extra": Unknown field."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -498,12 +475,10 @@ fn does_not_allow_non_nullable_input_to_be_omitted_in_variable() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$value" of required type "String!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$value" of required type "String!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -520,12 +495,10 @@ fn does_not_allow_non_nullable_input_to_be_set_to_null_in_variable() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$value" of required type "String!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$value" of required type "String!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -575,12 +548,10 @@ fn allow_lists_to_be_null() {
|
|||
fn allow_lists_to_contain_values() {
|
||||
run_variable_query(
|
||||
r#"query q($input: [String]) { list(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A")]),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A")]),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(
|
||||
|
@ -595,16 +566,14 @@ fn allow_lists_to_contain_values() {
|
|||
fn allow_lists_to_contain_null() {
|
||||
run_variable_query(
|
||||
r#"query q($input: [String]) { list(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![
|
||||
InputValue::string("A"),
|
||||
InputValue::null(),
|
||||
InputValue::string("B"),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![
|
||||
InputValue::string("A"),
|
||||
InputValue::null(),
|
||||
InputValue::string("B"),
|
||||
]),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(
|
||||
|
@ -628,12 +597,10 @@ fn does_not_allow_non_null_lists_to_be_null() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$input" of required type "[String]!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$input" of required type "[String]!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -641,12 +608,10 @@ fn does_not_allow_non_null_lists_to_be_null() {
|
|||
fn allow_non_null_lists_to_contain_values() {
|
||||
run_variable_query(
|
||||
r#"query q($input: [String]!) { nnList(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A")]),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A")]),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(result.get("nnList"), Some(&Value::string(r#"[Some("A")]"#)));
|
||||
|
@ -657,16 +622,14 @@ fn allow_non_null_lists_to_contain_values() {
|
|||
fn allow_non_null_lists_to_contain_null() {
|
||||
run_variable_query(
|
||||
r#"query q($input: [String]!) { nnList(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![
|
||||
InputValue::string("A"),
|
||||
InputValue::null(),
|
||||
InputValue::string("B"),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![
|
||||
InputValue::string("A"),
|
||||
InputValue::null(),
|
||||
InputValue::string("B"),
|
||||
]),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(
|
||||
|
@ -694,12 +657,10 @@ fn allow_lists_of_non_null_to_be_null() {
|
|||
fn allow_lists_of_non_null_to_contain_values() {
|
||||
run_variable_query(
|
||||
r#"query q($input: [String!]) { listNn(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A")]),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A")]),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(result.get("listNn"), Some(&Value::string(r#"Some(["A"])"#)));
|
||||
|
@ -712,16 +673,14 @@ fn does_not_allow_lists_of_non_null_to_contain_null() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($input: [String!]) { listNn(input: $input) }"#;
|
||||
let vars = vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![
|
||||
InputValue::string("A"),
|
||||
InputValue::null(),
|
||||
InputValue::string("B"),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
let vars = vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![
|
||||
InputValue::string("A"),
|
||||
InputValue::null(),
|
||||
InputValue::string("B"),
|
||||
]),
|
||||
)].into_iter()
|
||||
.collect();
|
||||
|
||||
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
|
||||
|
@ -739,16 +698,14 @@ fn does_not_allow_non_null_lists_of_non_null_to_contain_null() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($input: [String!]!) { nnListNn(input: $input) }"#;
|
||||
let vars = vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![
|
||||
InputValue::string("A"),
|
||||
InputValue::null(),
|
||||
InputValue::string("B"),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
let vars = vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![
|
||||
InputValue::string("A"),
|
||||
InputValue::null(),
|
||||
InputValue::string("B"),
|
||||
]),
|
||||
)].into_iter()
|
||||
.collect();
|
||||
|
||||
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
|
||||
|
@ -774,12 +731,10 @@ fn does_not_allow_non_null_lists_of_non_null_to_be_null() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$input" of required type "[String!]!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$input" of required type "[String!]!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -787,12 +742,10 @@ fn does_not_allow_non_null_lists_of_non_null_to_be_null() {
|
|||
fn allow_non_null_lists_of_non_null_to_contain_values() {
|
||||
run_variable_query(
|
||||
r#"query q($input: [String!]!) { nnListNn(input: $input) }"#,
|
||||
vec![
|
||||
(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A")]),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"input".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A")]),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(result.get("nnListNn"), Some(&Value::string(r#"["A"]"#)));
|
||||
|
@ -805,12 +758,10 @@ fn does_not_allow_invalid_types_to_be_used_as_values() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($input: TestType!) { fieldWithObjectInput(input: $input) }"#;
|
||||
let vars = vec![
|
||||
(
|
||||
"value".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A"), InputValue::string("B")]),
|
||||
),
|
||||
].into_iter()
|
||||
let vars = vec![(
|
||||
"value".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A"), InputValue::string("B")]),
|
||||
)].into_iter()
|
||||
.collect();
|
||||
|
||||
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
|
||||
|
@ -828,12 +779,10 @@ fn does_not_allow_unknown_types_to_be_used_as_values() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($input: UnknownType!) { fieldWithObjectInput(input: $input) }"#;
|
||||
let vars = vec![
|
||||
(
|
||||
"value".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A"), InputValue::string("B")]),
|
||||
),
|
||||
].into_iter()
|
||||
let vars = vec![(
|
||||
"value".to_owned(),
|
||||
InputValue::list(vec![InputValue::string("A"), InputValue::string("B")]),
|
||||
)].into_iter()
|
||||
.collect();
|
||||
|
||||
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
|
||||
|
@ -953,12 +902,10 @@ fn does_not_allow_missing_required_field() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Invalid value for argument "arg", expected type "ExampleInputObject!""#,
|
||||
&[SourcePosition::new(20, 0, 20)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Invalid value for argument "arg", expected type "ExampleInputObject!""#,
|
||||
&[SourcePosition::new(20, 0, 20)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -973,12 +920,10 @@ fn does_not_allow_null_in_required_field() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Invalid value for argument "arg", expected type "ExampleInputObject!""#,
|
||||
&[SourcePosition::new(20, 0, 20)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Invalid value for argument "arg", expected type "ExampleInputObject!""#,
|
||||
&[SourcePosition::new(20, 0, 20)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -993,12 +938,10 @@ fn does_not_allow_missing_variable_for_required_field() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$var" of required type "Int!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$var" of required type "Int!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1015,12 +958,10 @@ fn does_not_allow_null_variable_for_required_field() {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$var" of required type "Int!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$var" of required type "Int!" was not provided."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1116,12 +1057,10 @@ mod integers {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$var" got invalid value. Expected "Int"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$var" got invalid value. Expected "Int"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1138,12 +1077,10 @@ mod integers {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$var" got invalid value. Expected "Int"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$var" got invalid value. Expected "Int"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1196,12 +1133,10 @@ mod floats {
|
|||
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$var" got invalid value. Expected "Float"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
ValidationError(vec![RuleError::new(
|
||||
r#"Variable "$var" got invalid value. Expected "Float"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
)])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ pub mod graphiql;
|
|||
use serde::ser;
|
||||
use serde::ser::SerializeMap;
|
||||
|
||||
use {GraphQLError, GraphQLType, RootNode, Value, Variables};
|
||||
use ast::InputValue;
|
||||
use executor::ExecutionError;
|
||||
use {GraphQLError, GraphQLType, RootNode, Value, Variables};
|
||||
|
||||
/// The result of executing a query
|
||||
pub trait ExecutionResponse: ser::Serialize {
|
||||
|
@ -41,7 +41,8 @@ pub trait Executable {
|
|||
#[derive(Deserialize, Clone, Serialize, PartialEq, Debug)]
|
||||
pub struct GraphQLRequest {
|
||||
query: String,
|
||||
#[serde(rename = "operationName")] operation_name: Option<String>,
|
||||
#[serde(rename = "operationName")]
|
||||
operation_name: Option<String>,
|
||||
variables: Option<InputValue>,
|
||||
}
|
||||
|
||||
|
@ -166,22 +167,22 @@ impl<'a> ser::Serialize for GraphQLResponse<'a> {
|
|||
{
|
||||
match self.0 {
|
||||
Ok((ref res, ref err)) => {
|
||||
let mut map = try!(serializer.serialize_map(None));
|
||||
let mut map = serializer.serialize_map(None)?;
|
||||
|
||||
try!(map.serialize_key("data"));
|
||||
try!(map.serialize_value(res));
|
||||
map.serialize_key("data")?;
|
||||
map.serialize_value(res)?;
|
||||
|
||||
if !err.is_empty() {
|
||||
try!(map.serialize_key("errors"));
|
||||
try!(map.serialize_value(err));
|
||||
map.serialize_key("errors")?;
|
||||
map.serialize_value(err)?;
|
||||
}
|
||||
|
||||
map.end()
|
||||
}
|
||||
Err(ref err) => {
|
||||
let mut map = try!(serializer.serialize_map(Some(1)));
|
||||
try!(map.serialize_key("errors"));
|
||||
try!(map.serialize_value(err));
|
||||
let mut map = serializer.serialize_map(Some(1))?;
|
||||
map.serialize_key("errors")?;
|
||||
map.serialize_value(err)?;
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
@ -223,8 +224,8 @@ impl<'a> ser::Serialize for GraphQLBatchResponse<'a> {
|
|||
#[cfg(any(test, feature = "expose-test-schema"))]
|
||||
#[allow(missing_docs)]
|
||||
pub mod tests {
|
||||
use serde_json::Value as Json;
|
||||
use serde_json;
|
||||
use serde_json::Value as Json;
|
||||
|
||||
/// Normalized response content we expect to get back from
|
||||
/// the http framework integration we are testing.
|
||||
|
|
|
@ -169,9 +169,9 @@ mod integration_test {
|
|||
use chrono::Utc;
|
||||
|
||||
use executor::Variables;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
use indexmap::IndexMap;
|
||||
use serde::{de, ser};
|
||||
use serde::ser::SerializeMap;
|
||||
use serde::{de, ser};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use {GraphQLError, Value};
|
||||
use ast::InputValue;
|
||||
use executor::ExecutionError;
|
||||
use parser::{ParseError, SourcePosition, Spanning};
|
||||
use validation::RuleError;
|
||||
use {GraphQLError, Value};
|
||||
|
||||
impl ser::Serialize for ExecutionError {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: ser::Serializer,
|
||||
{
|
||||
let mut map = try!(serializer.serialize_map(Some(4)));
|
||||
let mut map = serializer.serialize_map(Some(4))?;
|
||||
|
||||
try!(map.serialize_key("message"));
|
||||
try!(map.serialize_value(self.error().message()));
|
||||
map.serialize_key("message")?;
|
||||
map.serialize_value(self.error().message())?;
|
||||
|
||||
let locations = vec![self.location()];
|
||||
try!(map.serialize_key("locations"));
|
||||
try!(map.serialize_value(&locations));
|
||||
map.serialize_key("locations")?;
|
||||
map.serialize_value(&locations)?;
|
||||
|
||||
try!(map.serialize_key("path"));
|
||||
try!(map.serialize_value(self.path()));
|
||||
map.serialize_key("path")?;
|
||||
map.serialize_value(self.path())?;
|
||||
|
||||
if !self.error().data().is_null() {
|
||||
try!(map.serialize_key("data"));
|
||||
try!(map.serialize_value(self.error().data()));
|
||||
map.serialize_key("data")?;
|
||||
map.serialize_value(self.error().data())?;
|
||||
}
|
||||
|
||||
map.end()
|
||||
|
@ -76,10 +76,15 @@ impl<'de> de::Deserialize<'de> for InputValue {
|
|||
where
|
||||
E: de::Error,
|
||||
{
|
||||
if value >= i32::min_value() as i64 && value <= i32::max_value() as i64 {
|
||||
if value >= i64::from(i32::min_value()) && value <= i64::from(i32::max_value()) {
|
||||
Ok(InputValue::int(value as i32))
|
||||
} else {
|
||||
Err(E::custom(format!("integer out of range")))
|
||||
// Browser's JSON.stringify serialize all numbers having no
|
||||
// fractional part as integers (no decimal point), so we
|
||||
// must parse large integers as floating point otherwise
|
||||
// we would error on transferring large floating point
|
||||
// numbers.
|
||||
Ok(InputValue::float(value as f64))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +95,12 @@ impl<'de> de::Deserialize<'de> for InputValue {
|
|||
if value <= i32::max_value() as u64 {
|
||||
self.visit_i64(value as i64)
|
||||
} else {
|
||||
Err(E::custom(format!("integer out of range")))
|
||||
// Browser's JSON.stringify serialize all numbers having no
|
||||
// fractional part as integers (no decimal point), so we
|
||||
// must parse large integers as floating point otherwise
|
||||
// we would error on transferring large floating point
|
||||
// numbers.
|
||||
Ok(InputValue::float(value as f64))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +133,7 @@ impl<'de> de::Deserialize<'de> for InputValue {
|
|||
{
|
||||
let mut values = Vec::new();
|
||||
|
||||
while let Some(el) = try!(visitor.next_element()) {
|
||||
while let Some(el) = visitor.next_element()? {
|
||||
values.push(el);
|
||||
}
|
||||
|
||||
|
@ -136,7 +146,7 @@ impl<'de> de::Deserialize<'de> for InputValue {
|
|||
{
|
||||
let mut values: IndexMap<String, InputValue> = IndexMap::new();
|
||||
|
||||
while let Some((key, value)) = try!(visitor.next_entry()) {
|
||||
while let Some((key, value)) = visitor.next_entry()? {
|
||||
values.insert(key, value);
|
||||
}
|
||||
|
||||
|
@ -155,7 +165,7 @@ impl ser::Serialize for InputValue {
|
|||
{
|
||||
match *self {
|
||||
InputValue::Null | InputValue::Variable(_) => serializer.serialize_unit(),
|
||||
InputValue::Int(v) => serializer.serialize_i64(v as i64),
|
||||
InputValue::Int(v) => serializer.serialize_i64(i64::from(v)),
|
||||
InputValue::Float(v) => serializer.serialize_f64(v),
|
||||
InputValue::String(ref v) | InputValue::Enum(ref v) => serializer.serialize_str(v),
|
||||
InputValue::Boolean(v) => serializer.serialize_bool(v),
|
||||
|
@ -176,13 +186,13 @@ impl ser::Serialize for RuleError {
|
|||
where
|
||||
S: ser::Serializer,
|
||||
{
|
||||
let mut map = try!(serializer.serialize_map(Some(2)));
|
||||
let mut map = serializer.serialize_map(Some(2))?;
|
||||
|
||||
try!(map.serialize_key("message"));
|
||||
try!(map.serialize_value(self.message()));
|
||||
map.serialize_key("message")?;
|
||||
map.serialize_value(self.message())?;
|
||||
|
||||
try!(map.serialize_key("locations"));
|
||||
try!(map.serialize_value(self.locations()));
|
||||
map.serialize_key("locations")?;
|
||||
map.serialize_value(self.locations())?;
|
||||
|
||||
map.end()
|
||||
}
|
||||
|
@ -193,15 +203,15 @@ impl ser::Serialize for SourcePosition {
|
|||
where
|
||||
S: ser::Serializer,
|
||||
{
|
||||
let mut map = try!(serializer.serialize_map(Some(2)));
|
||||
let mut map = serializer.serialize_map(Some(2))?;
|
||||
|
||||
let line = self.line() + 1;
|
||||
try!(map.serialize_key("line"));
|
||||
try!(map.serialize_value(&line));
|
||||
map.serialize_key("line")?;
|
||||
map.serialize_value(&line)?;
|
||||
|
||||
let column = self.column() + 1;
|
||||
try!(map.serialize_key("column"));
|
||||
try!(map.serialize_value(&column));
|
||||
map.serialize_key("column")?;
|
||||
map.serialize_value(&column)?;
|
||||
|
||||
map.end()
|
||||
}
|
||||
|
@ -212,11 +222,11 @@ impl<'a> ser::Serialize for Spanning<ParseError<'a>> {
|
|||
where
|
||||
S: ser::Serializer,
|
||||
{
|
||||
let mut map = try!(serializer.serialize_map(Some(2)));
|
||||
let mut map = serializer.serialize_map(Some(2))?;
|
||||
|
||||
let message = format!("{}", self.item);
|
||||
try!(map.serialize_key("message"));
|
||||
try!(map.serialize_value(&message));
|
||||
map.serialize_key("message")?;
|
||||
map.serialize_value(&message)?;
|
||||
|
||||
let mut location = IndexMap::new();
|
||||
location.insert("line".to_owned(), self.start.line() + 1);
|
||||
|
@ -224,8 +234,8 @@ impl<'a> ser::Serialize for Spanning<ParseError<'a>> {
|
|||
|
||||
let locations = vec![location];
|
||||
|
||||
try!(map.serialize_key("locations"));
|
||||
try!(map.serialize_value(&locations));
|
||||
map.serialize_key("locations")?;
|
||||
map.serialize_value(&locations)?;
|
||||
|
||||
map.end()
|
||||
}
|
||||
|
@ -238,7 +248,7 @@ impl ser::Serialize for Value {
|
|||
{
|
||||
match *self {
|
||||
Value::Null => serializer.serialize_unit(),
|
||||
Value::Int(v) => serializer.serialize_i64(v as i64),
|
||||
Value::Int(v) => serializer.serialize_i64(i64::from(v)),
|
||||
Value::Float(v) => serializer.serialize_f64(v),
|
||||
Value::String(ref v) => serializer.serialize_str(v),
|
||||
Value::Boolean(v) => serializer.serialize_bool(v),
|
||||
|
@ -247,3 +257,24 @@ impl ser::Serialize for Value {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::from_str;
|
||||
use ast::InputValue;
|
||||
|
||||
#[test]
|
||||
fn int() {
|
||||
assert_eq!(from_str::<InputValue>("1235").unwrap(),
|
||||
InputValue::int(1235));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn float() {
|
||||
assert_eq!(from_str::<InputValue>("2.0").unwrap(),
|
||||
InputValue::float(2.0));
|
||||
// large value without a decimal part is also float
|
||||
assert_eq!(from_str::<InputValue>("123567890123").unwrap(),
|
||||
InputValue::float(123567890123.0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,16 +122,16 @@ mod value;
|
|||
#[macro_use]
|
||||
mod macros;
|
||||
mod ast;
|
||||
pub mod parser;
|
||||
mod types;
|
||||
mod schema;
|
||||
mod validation;
|
||||
mod util;
|
||||
mod executor;
|
||||
pub mod parser;
|
||||
mod schema;
|
||||
mod types;
|
||||
mod util;
|
||||
mod validation;
|
||||
// This needs to be public until docs have support for private modules:
|
||||
// https://github.com/rust-lang/cargo/issues/1520
|
||||
pub mod integrations;
|
||||
pub mod http;
|
||||
pub mod integrations;
|
||||
// TODO: remove this alias export in 0.10. (breaking change)
|
||||
pub use http::graphiql;
|
||||
|
||||
|
@ -146,18 +146,19 @@ mod executor_tests;
|
|||
// Needs to be public because macros use it.
|
||||
pub use util::to_camel_case;
|
||||
|
||||
use executor::execute_validated_query;
|
||||
use parser::{parse_document_source, ParseError, Spanning};
|
||||
use validation::{validate_input_values, visit_all_rules, ValidatorContext};
|
||||
use executor::execute_validated_query;
|
||||
|
||||
pub use ast::{FromInputValue, InputValue, Selection, ToInputValue, Type};
|
||||
pub use value::Value;
|
||||
pub use types::base::{Arguments, GraphQLType, TypeKind};
|
||||
pub use executor::{Context, ExecutionError, ExecutionResult, Executor, FieldError, FieldResult,
|
||||
FromContext, IntoResolvable, Registry, Variables};
|
||||
pub use validation::RuleError;
|
||||
pub use types::scalars::{EmptyMutation, ID};
|
||||
pub use executor::{Applies, LookAheadArgument, LookAheadSelection, LookAheadValue, LookAheadMethods};
|
||||
pub use schema::model::RootNode;
|
||||
pub use types::base::{Arguments, GraphQLType, TypeKind};
|
||||
pub use types::scalars::{EmptyMutation, ID};
|
||||
pub use validation::RuleError;
|
||||
pub use value::Value;
|
||||
|
||||
pub use schema::meta;
|
||||
|
||||
|
@ -184,7 +185,7 @@ where
|
|||
QueryT: GraphQLType<Context = CtxT>,
|
||||
MutationT: GraphQLType<Context = CtxT>,
|
||||
{
|
||||
let document = try!(parse_document_source(document_source));
|
||||
let document = parse_document_source(document_source)?;
|
||||
|
||||
{
|
||||
let errors = validate_input_values(variables, &document, &root_node.schema);
|
||||
|
|
|
@ -57,7 +57,7 @@ macro_rules! graphql_scalar {
|
|||
// and body for the from() method on FromInputValue.
|
||||
(
|
||||
@generate,
|
||||
( $name:ty, $outname:tt, $descr:tt ),
|
||||
( $name:ty, $outname:expr, $descr:tt ),
|
||||
(
|
||||
( $resolve_selfvar:ident, $resolve_body:block ),
|
||||
( $fiv_arg:ident, $fiv_result:ty, $fiv_body:block )
|
||||
|
@ -135,7 +135,7 @@ macro_rules! graphql_scalar {
|
|||
// description: <description>
|
||||
(
|
||||
@parse,
|
||||
( $name:ty, $outname:tt, $_ignored:tt ),
|
||||
( $name:ty, $outname:expr, $_ignored:tt ),
|
||||
$acc:tt,
|
||||
description: $descr:tt $($rest:tt)*
|
||||
) => {
|
||||
|
@ -151,6 +151,6 @@ macro_rules! graphql_scalar {
|
|||
// Entry point
|
||||
// RustName { ... }
|
||||
( $name:ty { $( $items:tt )* }) => {
|
||||
graphql_scalar!( @parse, ( $name, (stringify!($name)), None ), ( None, None ), $($items)* );
|
||||
graphql_scalar!( @parse, ( $name, stringify!($name), None ), ( None, None ), $($items)* );
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use executor::Variables;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct Root;
|
||||
|
||||
|
@ -192,7 +192,7 @@ fn introspect_field_exec_arg_and_more() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -225,7 +225,7 @@ fn introspect_field_single_arg() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -258,7 +258,7 @@ fn introspect_field_multi_args() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -284,7 +284,7 @@ fn introspect_field_multi_args() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -317,7 +317,7 @@ fn introspect_field_multi_args_trailing_comma() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -343,7 +343,7 @@ fn introspect_field_multi_args_trailing_comma() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -376,7 +376,7 @@ fn introspect_field_single_arg_descr() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -409,7 +409,7 @@ fn introspect_field_multi_args_descr() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -435,7 +435,7 @@ fn introspect_field_multi_args_descr() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -468,7 +468,7 @@ fn introspect_field_multi_args_descr_trailing_comma() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -494,7 +494,7 @@ fn introspect_field_multi_args_descr_trailing_comma() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -520,7 +520,7 @@ fn introspect_field_arg_with_default() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -546,7 +546,7 @@ fn introspect_field_multi_args_with_default() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -565,7 +565,7 @@ fn introspect_field_multi_args_with_default() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -591,7 +591,7 @@ fn introspect_field_multi_args_with_default_trailing_comma() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -610,7 +610,7 @@ fn introspect_field_multi_args_with_default_trailing_comma() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -636,7 +636,7 @@ fn introspect_field_arg_with_default_descr() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -662,7 +662,7 @@ fn introspect_field_multi_args_with_default_descr() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -681,7 +681,7 @@ fn introspect_field_multi_args_with_default_descr() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -707,7 +707,7 @@ fn introspect_field_multi_args_with_default_trailing_comma_descr() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -726,7 +726,7 @@ fn introspect_field_multi_args_with_default_trailing_comma_descr() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -752,7 +752,7 @@ fn introspect_field_args_with_complex_default() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -774,7 +774,7 @@ fn introspect_field_args_with_complex_default() {
|
|||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use indexmap::IndexMap;
|
||||
|
||||
use value::Value;
|
||||
use ast::InputValue;
|
||||
use schema::model::RootNode;
|
||||
use executor::FieldResult;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct Interface;
|
||||
struct Root;
|
||||
|
|
|
@ -2,9 +2,9 @@ use indexmap::IndexMap;
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use ast::InputValue;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
/*
|
||||
|
||||
|
@ -184,7 +184,7 @@ fn introspect_custom_name() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -200,7 +200,7 @@ fn introspect_with_lifetime() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -216,7 +216,7 @@ fn introspect_with_generics() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -235,7 +235,7 @@ fn introspect_description_first() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -254,7 +254,7 @@ fn introspect_fields_first() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -273,7 +273,7 @@ fn introspect_interfaces_first() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -295,7 +295,7 @@ fn introspect_commas_with_trailing() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -314,7 +314,7 @@ fn introspect_commas_on_meta() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -336,7 +336,7 @@ fn introspect_resolvers_with_trailing_comma() {
|
|||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
mod scalar;
|
||||
mod args;
|
||||
mod field;
|
||||
mod object;
|
||||
mod interface;
|
||||
mod object;
|
||||
mod scalar;
|
||||
mod union;
|
||||
|
|
|
@ -2,10 +2,10 @@ use indexmap::IndexMap;
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use ast::InputValue;
|
||||
use value::Value;
|
||||
use executor::{Context, FieldResult};
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use executor::{Context, FieldResult};
|
||||
use value::Value;
|
||||
|
||||
/*
|
||||
|
||||
|
@ -250,15 +250,13 @@ fn introspect_description_first() {
|
|||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
|
@ -278,15 +276,13 @@ fn introspect_fields_first() {
|
|||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
|
@ -306,15 +302,13 @@ fn introspect_interfaces_first() {
|
|||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
|
@ -337,15 +331,13 @@ fn introspect_commas_with_trailing() {
|
|||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
|
@ -365,15 +357,13 @@ fn introspect_commas_on_meta() {
|
|||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use indexmap::IndexMap;
|
||||
|
||||
use executor::Variables;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
struct DefaultName(i32);
|
||||
struct OtherOrder(i32);
|
||||
|
|
|
@ -2,9 +2,9 @@ use indexmap::IndexMap;
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use ast::InputValue;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
/*
|
||||
|
||||
|
@ -162,7 +162,7 @@ fn introspect_custom_name() {
|
|||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -178,7 +178,7 @@ fn introspect_with_lifetime() {
|
|||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -194,7 +194,7 @@ fn introspect_with_generics() {
|
|||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -213,7 +213,7 @@ fn introspect_description_first() {
|
|||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -232,7 +232,7 @@ fn introspect_resolvers_first() {
|
|||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -254,7 +254,7 @@ fn introspect_commas_with_trailing() {
|
|||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
@ -276,7 +276,7 @@ fn introspect_resolvers_with_trailing_comma() {
|
|||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
))
|
||||
);
|
||||
});
|
||||
|
|
|
@ -4,14 +4,14 @@ use ast::{Arguments, Definition, Directive, Document, Field, Fragment, FragmentS
|
|||
InlineFragment, InputValue, Operation, OperationType, Selection, Type,
|
||||
VariableDefinition, VariableDefinitions};
|
||||
|
||||
use parser::value::parse_value_literal;
|
||||
use parser::{Lexer, OptionParseResult, ParseError, ParseResult, Parser, Spanning, Token,
|
||||
UnlocatedParseResult};
|
||||
use parser::value::parse_value_literal;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn parse_document_source(s: &str) -> UnlocatedParseResult<Document> {
|
||||
let mut lexer = Lexer::new(s);
|
||||
let mut parser = try!(Parser::new(&mut lexer).map_err(|s| s.map(ParseError::LexerError)));
|
||||
let mut parser = Parser::new(&mut lexer).map_err(|s| s.map(ParseError::LexerError))?;
|
||||
parse_document(&mut parser)
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ fn parse_document<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Docum
|
|||
let mut defs = Vec::new();
|
||||
|
||||
loop {
|
||||
defs.push(try!(parse_definition(parser)));
|
||||
defs.push(parse_definition(parser)?);
|
||||
|
||||
if parser.peek().item == Token::EndOfFile {
|
||||
return Ok(defs);
|
||||
|
@ -29,19 +29,17 @@ fn parse_document<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Docum
|
|||
|
||||
fn parse_definition<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Definition<'a>> {
|
||||
match parser.peek().item {
|
||||
Token::CurlyOpen | Token::Name("query") | Token::Name("mutation") => Ok(
|
||||
Definition::Operation(try!(parse_operation_definition(parser))),
|
||||
),
|
||||
Token::Name("fragment") => Ok(Definition::Fragment(try!(parse_fragment_definition(
|
||||
parser
|
||||
)))),
|
||||
Token::CurlyOpen | Token::Name("query") | Token::Name("mutation") => {
|
||||
Ok(Definition::Operation(parse_operation_definition(parser)?))
|
||||
}
|
||||
Token::Name("fragment") => Ok(Definition::Fragment(parse_fragment_definition(parser)?)),
|
||||
_ => Err(parser.next()?.map(ParseError::UnexpectedToken)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Operation<'a>> {
|
||||
if parser.peek().item == Token::CurlyOpen {
|
||||
let selection_set = try!(parse_selection_set(parser));
|
||||
let selection_set = parse_selection_set(parser)?;
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&selection_set.start,
|
||||
|
@ -56,14 +54,14 @@ fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Op
|
|||
))
|
||||
} else {
|
||||
let start_pos = parser.peek().start.clone();
|
||||
let operation_type = try!(parse_operation_type(parser));
|
||||
let operation_type = parse_operation_type(parser)?;
|
||||
let name = match parser.peek().item {
|
||||
Token::Name(_) => Some(try!(parser.expect_name())),
|
||||
Token::Name(_) => Some(parser.expect_name()?),
|
||||
_ => None,
|
||||
};
|
||||
let variable_definitions = try!(parse_variable_definitions(parser));
|
||||
let directives = try!(parse_directives(parser));
|
||||
let selection_set = try!(parse_selection_set(parser));
|
||||
let variable_definitions = parse_variable_definitions(parser)?;
|
||||
let directives = parse_directives(parser)?;
|
||||
let selection_set = parse_selection_set(parser)?;
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&start_pos,
|
||||
|
@ -82,7 +80,7 @@ fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Op
|
|||
fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fragment<'a>> {
|
||||
let Spanning {
|
||||
start: start_pos, ..
|
||||
} = try!(parser.expect(&Token::Name("fragment")));
|
||||
} = parser.expect(&Token::Name("fragment"))?;
|
||||
let name = match parser.expect_name() {
|
||||
Ok(n) => if n.item == "on" {
|
||||
return Err(n.map(|_| ParseError::UnexpectedToken(Token::Name("on"))));
|
||||
|
@ -92,10 +90,10 @@ fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fra
|
|||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
try!(parser.expect(&Token::Name("on")));
|
||||
let type_cond = try!(parser.expect_name());
|
||||
let directives = try!(parse_directives(parser));
|
||||
let selection_set = try!(parse_selection_set(parser));
|
||||
parser.expect(&Token::Name("on"))?;
|
||||
let type_cond = parser.expect_name()?;
|
||||
let directives = parse_directives(parser)?;
|
||||
let selection_set = parse_selection_set(parser)?;
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&start_pos,
|
||||
|
@ -113,7 +111,7 @@ fn parse_optional_selection_set<'a>(
|
|||
parser: &mut Parser<'a>,
|
||||
) -> OptionParseResult<'a, Vec<Selection<'a>>> {
|
||||
if parser.peek().item == Token::CurlyOpen {
|
||||
Ok(Some(try!(parse_selection_set(parser))))
|
||||
Ok(Some(parse_selection_set(parser)?))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -134,14 +132,14 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
|
|||
let Spanning {
|
||||
start: ref start_pos,
|
||||
..
|
||||
} = try!(parser.expect(&Token::Ellipsis));
|
||||
} = parser.expect(&Token::Ellipsis)?;
|
||||
|
||||
match parser.peek().item {
|
||||
Token::Name("on") => {
|
||||
parser.next()?;
|
||||
let name = try!(parser.expect_name());
|
||||
let directives = try!(parse_directives(parser));
|
||||
let selection_set = try!(parse_selection_set(parser));
|
||||
let name = parser.expect_name()?;
|
||||
let directives = parse_directives(parser)?;
|
||||
let selection_set = parse_selection_set(parser)?;
|
||||
|
||||
Ok(Selection::InlineFragment(Spanning::start_end(
|
||||
&start_pos.clone(),
|
||||
|
@ -154,7 +152,7 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
|
|||
)))
|
||||
}
|
||||
Token::CurlyOpen => {
|
||||
let selection_set = try!(parse_selection_set(parser));
|
||||
let selection_set = parse_selection_set(parser)?;
|
||||
|
||||
Ok(Selection::InlineFragment(Spanning::start_end(
|
||||
&start_pos.clone(),
|
||||
|
@ -167,8 +165,8 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
|
|||
)))
|
||||
}
|
||||
Token::Name(_) => {
|
||||
let frag_name = try!(parser.expect_name());
|
||||
let directives = try!(parse_directives(parser));
|
||||
let frag_name = parser.expect_name()?;
|
||||
let directives = parse_directives(parser)?;
|
||||
|
||||
Ok(Selection::FragmentSpread(Spanning::start_end(
|
||||
&start_pos.clone(),
|
||||
|
@ -183,8 +181,8 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
|
|||
)))
|
||||
}
|
||||
Token::At => {
|
||||
let directives = try!(parse_directives(parser));
|
||||
let selection_set = try!(parse_selection_set(parser));
|
||||
let directives = parse_directives(parser)?;
|
||||
let selection_set = parse_selection_set(parser)?;
|
||||
|
||||
Ok(Selection::InlineFragment(Spanning::start_end(
|
||||
&start_pos.clone(),
|
||||
|
@ -201,17 +199,17 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
|
|||
}
|
||||
|
||||
fn parse_field<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Field<'a>> {
|
||||
let mut alias = Some(try!(parser.expect_name()));
|
||||
let mut alias = Some(parser.expect_name()?);
|
||||
|
||||
let name = if try!(parser.skip(&Token::Colon)).is_some() {
|
||||
try!(parser.expect_name())
|
||||
let name = if parser.skip(&Token::Colon)?.is_some() {
|
||||
parser.expect_name()?
|
||||
} else {
|
||||
alias.take().unwrap()
|
||||
};
|
||||
|
||||
let arguments = try!(parse_arguments(parser));
|
||||
let directives = try!(parse_directives(parser));
|
||||
let selection_set = try!(parse_optional_selection_set(parser));
|
||||
let arguments = parse_arguments(parser)?;
|
||||
let directives = parse_directives(parser)?;
|
||||
let selection_set = parse_optional_selection_set(parser)?;
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&alias.as_ref().unwrap_or(&name).start.clone(),
|
||||
|
@ -237,13 +235,11 @@ fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Argumen
|
|||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(
|
||||
try!(parser.delimited_nonempty_list(
|
||||
&Token::ParenOpen,
|
||||
parse_argument,
|
||||
&Token::ParenClose
|
||||
)).map(|args| Arguments {
|
||||
items: args.into_iter().map(|s| s.item).collect(),
|
||||
}),
|
||||
parser
|
||||
.delimited_nonempty_list(&Token::ParenOpen, parse_argument, &Token::ParenClose)?
|
||||
.map(|args| Arguments {
|
||||
items: args.into_iter().map(|s| s.item).collect(),
|
||||
}),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -251,9 +247,9 @@ fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Argumen
|
|||
fn parse_argument<'a>(
|
||||
parser: &mut Parser<'a>,
|
||||
) -> ParseResult<'a, (Spanning<&'a str>, Spanning<InputValue>)> {
|
||||
let name = try!(parser.expect_name());
|
||||
try!(parser.expect(&Token::Colon));
|
||||
let value = try!(parse_value_literal(parser, false));
|
||||
let name = parser.expect_name()?;
|
||||
parser.expect(&Token::Colon)?;
|
||||
let value = parse_value_literal(parser, false)?;
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&name.start.clone(),
|
||||
|
@ -277,13 +273,15 @@ fn parse_variable_definitions<'a>(
|
|||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(
|
||||
try!(parser.delimited_nonempty_list(
|
||||
&Token::ParenOpen,
|
||||
parse_variable_definition,
|
||||
&Token::ParenClose
|
||||
)).map(|defs| VariableDefinitions {
|
||||
items: defs.into_iter().map(|s| s.item).collect(),
|
||||
}),
|
||||
parser
|
||||
.delimited_nonempty_list(
|
||||
&Token::ParenOpen,
|
||||
parse_variable_definition,
|
||||
&Token::ParenClose,
|
||||
)?
|
||||
.map(|defs| VariableDefinitions {
|
||||
items: defs.into_iter().map(|s| s.item).collect(),
|
||||
}),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -293,13 +291,13 @@ fn parse_variable_definition<'a>(
|
|||
) -> ParseResult<'a, (Spanning<&'a str>, VariableDefinition<'a>)> {
|
||||
let Spanning {
|
||||
start: start_pos, ..
|
||||
} = try!(parser.expect(&Token::Dollar));
|
||||
let var_name = try!(parser.expect_name());
|
||||
try!(parser.expect(&Token::Colon));
|
||||
let var_type = try!(parse_type(parser));
|
||||
} = parser.expect(&Token::Dollar)?;
|
||||
let var_name = parser.expect_name()?;
|
||||
parser.expect(&Token::Colon)?;
|
||||
let var_type = parse_type(parser)?;
|
||||
|
||||
let default_value = if try!(parser.skip(&Token::Equals)).is_some() {
|
||||
Some(try!(parse_value_literal(parser, true)))
|
||||
let default_value = if parser.skip(&Token::Equals)?.is_some() {
|
||||
Some(parse_value_literal(parser, true)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -328,7 +326,7 @@ fn parse_directives<'a>(
|
|||
} else {
|
||||
let mut items = Vec::new();
|
||||
while parser.peek().item == Token::At {
|
||||
items.push(try!(parse_directive(parser)));
|
||||
items.push(parse_directive(parser)?);
|
||||
}
|
||||
|
||||
Ok(Spanning::spanning(items))
|
||||
|
@ -338,9 +336,9 @@ fn parse_directives<'a>(
|
|||
fn parse_directive<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Directive<'a>> {
|
||||
let Spanning {
|
||||
start: start_pos, ..
|
||||
} = try!(parser.expect(&Token::At));
|
||||
let name = try!(parser.expect_name());
|
||||
let arguments = try!(parse_arguments(parser));
|
||||
} = parser.expect(&Token::At)?;
|
||||
let name = parser.expect_name()?;
|
||||
let arguments = parse_arguments(parser)?;
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&start_pos,
|
||||
|
@ -355,20 +353,20 @@ fn parse_directive<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Directive<'a>
|
|||
pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Type<'a>> {
|
||||
let parsed_type = if let Some(Spanning {
|
||||
start: start_pos, ..
|
||||
}) = try!(parser.skip(&Token::BracketOpen))
|
||||
}) = parser.skip(&Token::BracketOpen)?
|
||||
{
|
||||
let inner_type = try!(parse_type(parser));
|
||||
let Spanning { end: end_pos, .. } = try!(parser.expect(&Token::BracketClose));
|
||||
let inner_type = parse_type(parser)?;
|
||||
let Spanning { end: end_pos, .. } = parser.expect(&Token::BracketClose)?;
|
||||
Spanning::start_end(&start_pos, &end_pos, Type::List(Box::new(inner_type.item)))
|
||||
} else {
|
||||
try!(parser.expect_name()).map(|s| Type::Named(Cow::Borrowed(s)))
|
||||
parser.expect_name()?.map(|s| Type::Named(Cow::Borrowed(s)))
|
||||
};
|
||||
|
||||
Ok(match *parser.peek() {
|
||||
Spanning {
|
||||
item: Token::ExclamationMark,
|
||||
..
|
||||
} => try!(wrap_non_null(parser, parsed_type)),
|
||||
} => wrap_non_null(parser, parsed_type)?,
|
||||
_ => parsed_type,
|
||||
})
|
||||
}
|
||||
|
@ -377,7 +375,7 @@ fn wrap_non_null<'a>(
|
|||
parser: &mut Parser<'a>,
|
||||
inner: Spanning<Type<'a>>,
|
||||
) -> ParseResult<'a, Type<'a>> {
|
||||
let Spanning { end: end_pos, .. } = try!(parser.expect(&Token::ExclamationMark));
|
||||
let Spanning { end: end_pos, .. } = parser.expect(&Token::ExclamationMark)?;
|
||||
|
||||
let wrapped = match inner.item {
|
||||
Type::Named(name) => Type::NonNullNamed(name),
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::char;
|
||||
use std::str::CharIndices;
|
||||
use std::fmt;
|
||||
use std::iter::{Iterator, Peekable};
|
||||
use std::result::Result;
|
||||
use std::fmt;
|
||||
use std::str::CharIndices;
|
||||
|
||||
use parser::{SourcePosition, Spanning};
|
||||
|
||||
|
@ -160,10 +160,10 @@ impl<'a> Lexer<'a> {
|
|||
let start_pos = self.position.clone();
|
||||
|
||||
for _ in 0..3 {
|
||||
let (_, ch) = try!(self.next_char().ok_or(Spanning::zero_width(
|
||||
let (_, ch) = self.next_char().ok_or(Spanning::zero_width(
|
||||
&self.position,
|
||||
LexerError::UnexpectedEndOfFile
|
||||
)));
|
||||
LexerError::UnexpectedEndOfFile,
|
||||
))?;
|
||||
if ch != '.' {
|
||||
return Err(Spanning::zero_width(
|
||||
&start_pos,
|
||||
|
@ -181,10 +181,10 @@ impl<'a> Lexer<'a> {
|
|||
|
||||
fn scan_name(&mut self) -> LexerResult<'a> {
|
||||
let start_pos = self.position.clone();
|
||||
let (start_idx, start_ch) = try!(self.next_char().ok_or(Spanning::zero_width(
|
||||
let (start_idx, start_ch) = self.next_char().ok_or(Spanning::zero_width(
|
||||
&self.position,
|
||||
LexerError::UnexpectedEndOfFile
|
||||
)));
|
||||
LexerError::UnexpectedEndOfFile,
|
||||
))?;
|
||||
assert!(is_name_start(start_ch));
|
||||
|
||||
let mut end_idx = start_idx;
|
||||
|
@ -207,10 +207,10 @@ impl<'a> Lexer<'a> {
|
|||
|
||||
fn scan_string(&mut self) -> LexerResult<'a> {
|
||||
let start_pos = self.position.clone();
|
||||
let (_, start_ch) = try!(self.next_char().ok_or(Spanning::zero_width(
|
||||
let (_, start_ch) = self.next_char().ok_or(Spanning::zero_width(
|
||||
&self.position,
|
||||
LexerError::UnexpectedEndOfFile
|
||||
)));
|
||||
LexerError::UnexpectedEndOfFile,
|
||||
))?;
|
||||
assert!(start_ch == '"');
|
||||
|
||||
let mut acc = String::new();
|
||||
|
@ -262,7 +262,7 @@ impl<'a> Lexer<'a> {
|
|||
Some((_, 'u')) => {
|
||||
let start_pos = self.position.clone();
|
||||
self.next_char();
|
||||
acc.push(try!(self.scan_escaped_unicode(&start_pos)));
|
||||
acc.push(self.scan_escaped_unicode(&start_pos)?);
|
||||
}
|
||||
Some((_, ch)) => {
|
||||
let mut s = String::from("\\");
|
||||
|
@ -314,18 +314,18 @@ impl<'a> Lexer<'a> {
|
|||
&mut self,
|
||||
start_pos: &SourcePosition,
|
||||
) -> Result<char, Spanning<LexerError>> {
|
||||
let (start_idx, _) = try!(self.peek_char().ok_or(Spanning::zero_width(
|
||||
let (start_idx, _) = self.peek_char().ok_or(Spanning::zero_width(
|
||||
&self.position,
|
||||
LexerError::UnterminatedString
|
||||
)));
|
||||
LexerError::UnterminatedString,
|
||||
))?;
|
||||
let mut end_idx = start_idx;
|
||||
let mut len = 0;
|
||||
|
||||
for _ in 0..4 {
|
||||
let (idx, ch) = try!(self.next_char().ok_or(Spanning::zero_width(
|
||||
let (idx, ch) = self.next_char().ok_or(Spanning::zero_width(
|
||||
&self.position,
|
||||
LexerError::UnterminatedString
|
||||
)));
|
||||
LexerError::UnterminatedString,
|
||||
))?;
|
||||
|
||||
if !ch.is_alphanumeric() {
|
||||
break;
|
||||
|
@ -344,12 +344,12 @@ impl<'a> Lexer<'a> {
|
|||
));
|
||||
}
|
||||
|
||||
let code_point = try!(
|
||||
u32::from_str_radix(escape, 16).map_err(|_| Spanning::zero_width(
|
||||
let code_point = u32::from_str_radix(escape, 16).map_err(|_| {
|
||||
Spanning::zero_width(
|
||||
start_pos,
|
||||
LexerError::UnknownEscapeSequence("\\u".to_owned() + escape),
|
||||
))
|
||||
);
|
||||
)
|
||||
})?;
|
||||
|
||||
char::from_u32(code_point).ok_or_else(|| {
|
||||
Spanning::zero_width(
|
||||
|
@ -361,14 +361,14 @@ impl<'a> Lexer<'a> {
|
|||
|
||||
fn scan_number(&mut self) -> LexerResult<'a> {
|
||||
let start_pos = self.position.clone();
|
||||
let int_part = try!(self.scan_integer_part());
|
||||
let int_part = self.scan_integer_part()?;
|
||||
let mut frac_part = None;
|
||||
let mut exp_part = None;
|
||||
|
||||
if let Some((_, '.')) = self.peek_char() {
|
||||
self.next_char();
|
||||
|
||||
frac_part = Some(try!(self.scan_digits()));
|
||||
frac_part = Some(self.scan_digits()?);
|
||||
}
|
||||
|
||||
if let Some((_, ch)) = self.peek_char() {
|
||||
|
@ -385,12 +385,12 @@ impl<'a> Lexer<'a> {
|
|||
self.next_char();
|
||||
}
|
||||
}
|
||||
exp_part = Some(if is_negative { -1 } else { 1 } * try!(self.scan_digits()));
|
||||
exp_part = Some(if is_negative { -1 } else { 1 } * self.scan_digits()?);
|
||||
}
|
||||
}
|
||||
|
||||
let mantissa = frac_part
|
||||
.map(|f| f as f64)
|
||||
.map(|f| f64::from(f))
|
||||
.map(|frac| {
|
||||
if frac > 0f64 {
|
||||
frac / 10f64.powf(frac.log10().floor() + 1f64)
|
||||
|
@ -400,26 +400,28 @@ impl<'a> Lexer<'a> {
|
|||
})
|
||||
.map(|m| if int_part < 0 { -m } else { m });
|
||||
|
||||
let exp = exp_part.map(|e| e as f64).map(|e| 10f64.powf(e));
|
||||
let exp = exp_part.map(|e| f64::from(e)).map(|e| 10f64.powf(e));
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&start_pos,
|
||||
&self.position,
|
||||
match (mantissa, exp) {
|
||||
(None, None) => Token::Int(int_part),
|
||||
(None, Some(exp)) => Token::Float((int_part as f64) * exp),
|
||||
(Some(mantissa), None) => Token::Float((int_part as f64) + mantissa),
|
||||
(Some(mantissa), Some(exp)) => Token::Float(((int_part as f64) + mantissa) * exp),
|
||||
(None, Some(exp)) => Token::Float((f64::from(int_part)) * exp),
|
||||
(Some(mantissa), None) => Token::Float((f64::from(int_part)) + mantissa),
|
||||
(Some(mantissa), Some(exp)) => {
|
||||
Token::Float(((f64::from(int_part)) + mantissa) * exp)
|
||||
}
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn scan_integer_part(&mut self) -> Result<i32, Spanning<LexerError>> {
|
||||
let is_negative = {
|
||||
let (_, init_ch) = try!(self.peek_char().ok_or(Spanning::zero_width(
|
||||
let (_, init_ch) = self.peek_char().ok_or(Spanning::zero_width(
|
||||
&self.position,
|
||||
LexerError::UnexpectedEndOfFile
|
||||
)));
|
||||
LexerError::UnexpectedEndOfFile,
|
||||
))?;
|
||||
|
||||
if init_ch == '-' {
|
||||
self.next_char();
|
||||
|
@ -429,10 +431,10 @@ impl<'a> Lexer<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
let (_, ch) = try!(self.peek_char().ok_or(Spanning::zero_width(
|
||||
let (_, ch) = self.peek_char().ok_or(Spanning::zero_width(
|
||||
&self.position,
|
||||
LexerError::UnexpectedEndOfFile
|
||||
)));
|
||||
LexerError::UnexpectedEndOfFile,
|
||||
))?;
|
||||
|
||||
if ch == '0' {
|
||||
self.next_char();
|
||||
|
@ -445,16 +447,16 @@ impl<'a> Lexer<'a> {
|
|||
_ => Ok(0),
|
||||
}
|
||||
} else {
|
||||
Ok(try!(self.scan_digits()) * if is_negative { -1 } else { 1 })
|
||||
Ok(self.scan_digits()? * if is_negative { -1 } else { 1 })
|
||||
}
|
||||
}
|
||||
|
||||
fn scan_digits(&mut self) -> Result<i32, Spanning<LexerError>> {
|
||||
let start_pos = self.position.clone();
|
||||
let (start_idx, ch) = try!(self.peek_char().ok_or(Spanning::zero_width(
|
||||
let (start_idx, ch) = self.peek_char().ok_or(Spanning::zero_width(
|
||||
&self.position,
|
||||
LexerError::UnexpectedEndOfFile
|
||||
)));
|
||||
LexerError::UnexpectedEndOfFile,
|
||||
))?;
|
||||
let mut end_idx = start_idx;
|
||||
|
||||
if !ch.is_digit(10) {
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
//! Query parser and language utilities
|
||||
|
||||
mod utils;
|
||||
mod document;
|
||||
mod lexer;
|
||||
mod parser;
|
||||
mod utils;
|
||||
mod value;
|
||||
mod document;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use self::document::parse_document_source;
|
||||
|
||||
pub use self::parser::{OptionParseResult, ParseError, ParseResult, Parser, UnlocatedParseResult};
|
||||
pub use self::lexer::{Lexer, LexerError, Token};
|
||||
pub use self::parser::{OptionParseResult, ParseError, ParseResult, Parser, UnlocatedParseResult};
|
||||
pub use self::utils::{SourcePosition, Spanning};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::result::Result;
|
||||
use std::fmt;
|
||||
use std::result::Result;
|
||||
|
||||
use parser::{Lexer, LexerError, Spanning, Token};
|
||||
|
||||
|
@ -103,15 +103,15 @@ impl<'a> Parser<'a> {
|
|||
{
|
||||
let Spanning {
|
||||
start: start_pos, ..
|
||||
} = try!(self.expect(opening));
|
||||
} = self.expect(opening)?;
|
||||
let mut items = Vec::new();
|
||||
|
||||
loop {
|
||||
if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) {
|
||||
if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
|
||||
return Ok(Spanning::start_end(&start_pos, &end_pos, items));
|
||||
}
|
||||
|
||||
items.push(try!(parser(self)));
|
||||
items.push(parser(self)?);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,13 +128,13 @@ impl<'a> Parser<'a> {
|
|||
{
|
||||
let Spanning {
|
||||
start: start_pos, ..
|
||||
} = try!(self.expect(opening));
|
||||
} = self.expect(opening)?;
|
||||
let mut items = Vec::new();
|
||||
|
||||
loop {
|
||||
items.push(try!(parser(self)));
|
||||
items.push(parser(self)?);
|
||||
|
||||
if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) {
|
||||
if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
|
||||
return Ok(Spanning::start_end(&start_pos, &end_pos, items));
|
||||
}
|
||||
}
|
||||
|
@ -153,13 +153,13 @@ impl<'a> Parser<'a> {
|
|||
{
|
||||
let Spanning {
|
||||
start: start_pos, ..
|
||||
} = try!(self.expect(opening));
|
||||
} = self.expect(opening)?;
|
||||
let mut items = Vec::new();
|
||||
|
||||
loop {
|
||||
items.push(try!(parser(self)));
|
||||
items.push(parser(self)?);
|
||||
|
||||
if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) {
|
||||
if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
|
||||
return Ok(Spanning::start_end(&start_pos, &end_pos, items));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ast::{Arguments, Definition, Document, Field, InputValue, Operation, OperationType, Selection};
|
||||
use parser::{ParseError, SourcePosition, Spanning, Token};
|
||||
use parser::document::parse_document_source;
|
||||
use parser::{ParseError, SourcePosition, Spanning, Token};
|
||||
|
||||
fn parse_document(s: &str) -> Document {
|
||||
parse_document_source(s).expect(&format!("Parse error on input {:#?}", s))
|
||||
|
@ -26,85 +26,79 @@ fn simple_ast() {
|
|||
}
|
||||
"#
|
||||
),
|
||||
vec![
|
||||
Definition::Operation(Spanning::start_end(
|
||||
&SourcePosition::new(13, 1, 12),
|
||||
&SourcePosition::new(124, 6, 13),
|
||||
Operation {
|
||||
operation_type: OperationType::Query,
|
||||
name: None,
|
||||
variable_definitions: None,
|
||||
directives: None,
|
||||
selection_set: vec![
|
||||
Selection::Field(Spanning::start_end(
|
||||
vec![Definition::Operation(Spanning::start_end(
|
||||
&SourcePosition::new(13, 1, 12),
|
||||
&SourcePosition::new(124, 6, 13),
|
||||
Operation {
|
||||
operation_type: OperationType::Query,
|
||||
name: None,
|
||||
variable_definitions: None,
|
||||
directives: None,
|
||||
selection_set: vec![Selection::Field(Spanning::start_end(
|
||||
&SourcePosition::new(31, 2, 16),
|
||||
&SourcePosition::new(110, 5, 17),
|
||||
Field {
|
||||
alias: None,
|
||||
name: Spanning::start_end(
|
||||
&SourcePosition::new(31, 2, 16),
|
||||
&SourcePosition::new(110, 5, 17),
|
||||
Field {
|
||||
alias: None,
|
||||
name: Spanning::start_end(
|
||||
&SourcePosition::new(31, 2, 16),
|
||||
&SourcePosition::new(35, 2, 20),
|
||||
"node",
|
||||
),
|
||||
arguments: Some(Spanning::start_end(
|
||||
&SourcePosition::new(35, 2, 20),
|
||||
&SourcePosition::new(42, 2, 27),
|
||||
Arguments {
|
||||
items: vec![
|
||||
(
|
||||
Spanning::start_end(
|
||||
&SourcePosition::new(36, 2, 21),
|
||||
&SourcePosition::new(38, 2, 23),
|
||||
"id",
|
||||
),
|
||||
Spanning::start_end(
|
||||
&SourcePosition::new(40, 2, 25),
|
||||
&SourcePosition::new(41, 2, 26),
|
||||
InputValue::int(4),
|
||||
),
|
||||
),
|
||||
],
|
||||
},
|
||||
)),
|
||||
directives: None,
|
||||
selection_set: Some(vec![
|
||||
Selection::Field(Spanning::start_end(
|
||||
&SourcePosition::new(65, 3, 20),
|
||||
&SourcePosition::new(67, 3, 22),
|
||||
Field {
|
||||
alias: None,
|
||||
name: Spanning::start_end(
|
||||
&SourcePosition::new(65, 3, 20),
|
||||
&SourcePosition::new(67, 3, 22),
|
||||
"id",
|
||||
),
|
||||
arguments: None,
|
||||
directives: None,
|
||||
selection_set: None,
|
||||
},
|
||||
)),
|
||||
Selection::Field(Spanning::start_end(
|
||||
&SourcePosition::new(88, 4, 20),
|
||||
&SourcePosition::new(92, 4, 24),
|
||||
Field {
|
||||
alias: None,
|
||||
name: Spanning::start_end(
|
||||
&SourcePosition::new(88, 4, 20),
|
||||
&SourcePosition::new(92, 4, 24),
|
||||
"name",
|
||||
),
|
||||
arguments: None,
|
||||
directives: None,
|
||||
selection_set: None,
|
||||
},
|
||||
)),
|
||||
]),
|
||||
&SourcePosition::new(35, 2, 20),
|
||||
"node",
|
||||
),
|
||||
arguments: Some(Spanning::start_end(
|
||||
&SourcePosition::new(35, 2, 20),
|
||||
&SourcePosition::new(42, 2, 27),
|
||||
Arguments {
|
||||
items: vec![(
|
||||
Spanning::start_end(
|
||||
&SourcePosition::new(36, 2, 21),
|
||||
&SourcePosition::new(38, 2, 23),
|
||||
"id",
|
||||
),
|
||||
Spanning::start_end(
|
||||
&SourcePosition::new(40, 2, 25),
|
||||
&SourcePosition::new(41, 2, 26),
|
||||
InputValue::int(4),
|
||||
),
|
||||
)],
|
||||
},
|
||||
)),
|
||||
],
|
||||
},
|
||||
)),
|
||||
]
|
||||
directives: None,
|
||||
selection_set: Some(vec![
|
||||
Selection::Field(Spanning::start_end(
|
||||
&SourcePosition::new(65, 3, 20),
|
||||
&SourcePosition::new(67, 3, 22),
|
||||
Field {
|
||||
alias: None,
|
||||
name: Spanning::start_end(
|
||||
&SourcePosition::new(65, 3, 20),
|
||||
&SourcePosition::new(67, 3, 22),
|
||||
"id",
|
||||
),
|
||||
arguments: None,
|
||||
directives: None,
|
||||
selection_set: None,
|
||||
},
|
||||
)),
|
||||
Selection::Field(Spanning::start_end(
|
||||
&SourcePosition::new(88, 4, 20),
|
||||
&SourcePosition::new(92, 4, 24),
|
||||
Field {
|
||||
alias: None,
|
||||
name: Spanning::start_end(
|
||||
&SourcePosition::new(88, 4, 20),
|
||||
&SourcePosition::new(92, 4, 24),
|
||||
"name",
|
||||
),
|
||||
arguments: None,
|
||||
directives: None,
|
||||
selection_set: None,
|
||||
},
|
||||
)),
|
||||
]),
|
||||
},
|
||||
))],
|
||||
},
|
||||
))]
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -50,9 +50,10 @@ fn tokenize_error(s: &str) -> Spanning<LexerError> {
|
|||
fn empty_source() {
|
||||
assert_eq!(
|
||||
tokenize_to_vec(""),
|
||||
vec![
|
||||
Spanning::zero_width(&SourcePosition::new_origin(), Token::EndOfFile),
|
||||
]
|
||||
vec![Spanning::zero_width(
|
||||
&SourcePosition::new_origin(),
|
||||
Token::EndOfFile,
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use indexmap::IndexMap;
|
||||
|
||||
use ast::InputValue;
|
||||
use parser::{Lexer, Parser, SourcePosition, Spanning};
|
||||
use parser::value::parse_value_literal;
|
||||
use parser::{Lexer, Parser, SourcePosition, Spanning};
|
||||
|
||||
fn parse_value(s: &str) -> Spanning<InputValue> {
|
||||
let mut lexer = Lexer::new(s);
|
||||
|
@ -142,20 +142,18 @@ fn input_value_literals() {
|
|||
Spanning::start_end(
|
||||
&SourcePosition::new(18, 0, 18),
|
||||
&SourcePosition::new(30, 0, 30),
|
||||
InputValue::parsed_object(vec![
|
||||
(
|
||||
Spanning::start_end(
|
||||
&SourcePosition::new(19, 0, 19),
|
||||
&SourcePosition::new(22, 0, 22),
|
||||
"foo".to_owned(),
|
||||
),
|
||||
Spanning::start_end(
|
||||
&SourcePosition::new(24, 0, 24),
|
||||
&SourcePosition::new(29, 0, 29),
|
||||
InputValue::string("bar"),
|
||||
),
|
||||
InputValue::parsed_object(vec![(
|
||||
Spanning::start_end(
|
||||
&SourcePosition::new(19, 0, 19),
|
||||
&SourcePosition::new(22, 0, 22),
|
||||
"foo".to_owned(),
|
||||
),
|
||||
]),
|
||||
Spanning::start_end(
|
||||
&SourcePosition::new(24, 0, 24),
|
||||
&SourcePosition::new(29, 0, 29),
|
||||
InputValue::string("bar"),
|
||||
),
|
||||
)]),
|
||||
),
|
||||
),
|
||||
])
|
||||
|
|
|
@ -63,33 +63,37 @@ pub fn parse_value_literal<'a>(
|
|||
}
|
||||
|
||||
fn parse_list_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> ParseResult<'a, InputValue> {
|
||||
Ok(try!(parser.delimited_list(
|
||||
&Token::BracketOpen,
|
||||
|p| parse_value_literal(p, is_const),
|
||||
&Token::BracketClose
|
||||
)).map(InputValue::parsed_list))
|
||||
Ok(parser
|
||||
.delimited_list(
|
||||
&Token::BracketOpen,
|
||||
|p| parse_value_literal(p, is_const),
|
||||
&Token::BracketClose,
|
||||
)?
|
||||
.map(InputValue::parsed_list))
|
||||
}
|
||||
|
||||
fn parse_object_literal<'a>(
|
||||
parser: &mut Parser<'a>,
|
||||
is_const: bool,
|
||||
) -> ParseResult<'a, InputValue> {
|
||||
Ok(try!(parser.delimited_list(
|
||||
&Token::CurlyOpen,
|
||||
|p| parse_object_field(p, is_const),
|
||||
&Token::CurlyClose
|
||||
)).map(|items| InputValue::parsed_object(items.into_iter().map(|s| s.item).collect())))
|
||||
Ok(parser
|
||||
.delimited_list(
|
||||
&Token::CurlyOpen,
|
||||
|p| parse_object_field(p, is_const),
|
||||
&Token::CurlyClose,
|
||||
)?
|
||||
.map(|items| InputValue::parsed_object(items.into_iter().map(|s| s.item).collect())))
|
||||
}
|
||||
|
||||
fn parse_object_field<'a>(
|
||||
parser: &mut Parser<'a>,
|
||||
is_const: bool,
|
||||
) -> ParseResult<'a, (Spanning<String>, Spanning<InputValue>)> {
|
||||
let key = try!(parser.expect_name());
|
||||
let key = parser.expect_name()?;
|
||||
|
||||
try!(parser.expect(&Token::Colon));
|
||||
parser.expect(&Token::Colon)?;
|
||||
|
||||
let value = try!(parse_value_literal(parser, is_const));
|
||||
let value = parse_value_literal(parser, is_const)?;
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&key.start.clone(),
|
||||
|
@ -101,12 +105,12 @@ fn parse_object_field<'a>(
|
|||
fn parse_variable_literal<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, InputValue> {
|
||||
let Spanning {
|
||||
start: start_pos, ..
|
||||
} = try!(parser.expect(&Token::Dollar));
|
||||
} = parser.expect(&Token::Dollar)?;
|
||||
let Spanning {
|
||||
item: name,
|
||||
end: end_pos,
|
||||
..
|
||||
} = try!(parser.expect_name());
|
||||
} = parser.expect_name()?;
|
||||
|
||||
Ok(Spanning::start_end(
|
||||
&start_pos,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! Types used to describe a GraphQL schema
|
||||
//! Types used to describe a `GraphQL` schema
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
@ -8,62 +8,85 @@ use types::base::TypeKind;
|
|||
|
||||
/// Scalar type metadata
|
||||
pub struct ScalarMeta<'a> {
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
}
|
||||
|
||||
/// List type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct ListMeta<'a> {
|
||||
#[doc(hidden)] pub of_type: Type<'a>,
|
||||
#[doc(hidden)]
|
||||
pub of_type: Type<'a>,
|
||||
}
|
||||
|
||||
/// Nullable type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct NullableMeta<'a> {
|
||||
#[doc(hidden)] pub of_type: Type<'a>,
|
||||
#[doc(hidden)]
|
||||
pub of_type: Type<'a>,
|
||||
}
|
||||
|
||||
/// Object type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectMeta<'a> {
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub fields: Vec<Field<'a>>,
|
||||
#[doc(hidden)] pub interface_names: Vec<String>,
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub fields: Vec<Field<'a>>,
|
||||
#[doc(hidden)]
|
||||
pub interface_names: Vec<String>,
|
||||
}
|
||||
|
||||
/// Enum type metadata
|
||||
pub struct EnumMeta<'a> {
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub values: Vec<EnumValue>,
|
||||
#[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub values: Vec<EnumValue>,
|
||||
#[doc(hidden)]
|
||||
pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
}
|
||||
|
||||
/// Interface type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceMeta<'a> {
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub fields: Vec<Field<'a>>,
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub fields: Vec<Field<'a>>,
|
||||
}
|
||||
|
||||
/// Union type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct UnionMeta<'a> {
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub of_type_names: Vec<String>,
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub of_type_names: Vec<String>,
|
||||
}
|
||||
|
||||
/// Input object metadata
|
||||
pub struct InputObjectMeta<'a> {
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub input_fields: Vec<Argument<'a>>,
|
||||
#[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub input_fields: Vec<Argument<'a>>,
|
||||
#[doc(hidden)]
|
||||
pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
}
|
||||
|
||||
/// A placeholder for not-yet-registered types
|
||||
|
@ -72,40 +95,59 @@ pub struct InputObjectMeta<'a> {
|
|||
/// is inserted into a registry to indicate existence.
|
||||
#[derive(Debug)]
|
||||
pub struct PlaceholderMeta<'a> {
|
||||
#[doc(hidden)] pub of_type: Type<'a>,
|
||||
#[doc(hidden)]
|
||||
pub of_type: Type<'a>,
|
||||
}
|
||||
|
||||
/// Generic type metadata
|
||||
#[derive(Debug)]
|
||||
pub enum MetaType<'a> {
|
||||
#[doc(hidden)] Scalar(ScalarMeta<'a>),
|
||||
#[doc(hidden)] List(ListMeta<'a>),
|
||||
#[doc(hidden)] Nullable(NullableMeta<'a>),
|
||||
#[doc(hidden)] Object(ObjectMeta<'a>),
|
||||
#[doc(hidden)] Enum(EnumMeta<'a>),
|
||||
#[doc(hidden)] Interface(InterfaceMeta<'a>),
|
||||
#[doc(hidden)] Union(UnionMeta<'a>),
|
||||
#[doc(hidden)] InputObject(InputObjectMeta<'a>),
|
||||
#[doc(hidden)] Placeholder(PlaceholderMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Scalar(ScalarMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
List(ListMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Nullable(NullableMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Object(ObjectMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Enum(EnumMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Interface(InterfaceMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Union(UnionMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
InputObject(InputObjectMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Placeholder(PlaceholderMeta<'a>),
|
||||
}
|
||||
|
||||
/// Metadata for a field
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Field<'a> {
|
||||
#[doc(hidden)] pub name: String,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub arguments: Option<Vec<Argument<'a>>>,
|
||||
#[doc(hidden)] pub field_type: Type<'a>,
|
||||
#[doc(hidden)] pub deprecation_reason: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub name: String,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub arguments: Option<Vec<Argument<'a>>>,
|
||||
#[doc(hidden)]
|
||||
pub field_type: Type<'a>,
|
||||
#[doc(hidden)]
|
||||
pub deprecation_reason: Option<String>,
|
||||
}
|
||||
|
||||
/// Metadata for an argument to a field
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Argument<'a> {
|
||||
#[doc(hidden)] pub name: String,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub arg_type: Type<'a>,
|
||||
#[doc(hidden)] pub default_value: Option<InputValue>,
|
||||
#[doc(hidden)]
|
||||
pub name: String,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub arg_type: Type<'a>,
|
||||
#[doc(hidden)]
|
||||
pub default_value: Option<InputValue>,
|
||||
}
|
||||
|
||||
/// Metadata for a single value in an enum
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
pub mod meta;
|
||||
pub mod model;
|
||||
pub mod schema;
|
||||
pub mod meta;
|
||||
|
|
|
@ -2,22 +2,27 @@ use std::fmt;
|
|||
|
||||
use fnv::FnvHashMap;
|
||||
|
||||
use ast::Type;
|
||||
use executor::{Context, Registry};
|
||||
use schema::meta::{Argument, InterfaceMeta, MetaType, ObjectMeta, PlaceholderMeta, UnionMeta};
|
||||
use types::base::GraphQLType;
|
||||
use types::name::Name;
|
||||
use executor::{Context, Registry};
|
||||
use ast::Type;
|
||||
use schema::meta::{Argument, InterfaceMeta, MetaType, ObjectMeta, PlaceholderMeta, UnionMeta};
|
||||
|
||||
/// Root query node of a schema
|
||||
///
|
||||
/// This brings the mutation and query types together, and provides the
|
||||
/// predefined metadata fields.
|
||||
pub struct RootNode<'a, QueryT: GraphQLType, MutationT: GraphQLType> {
|
||||
#[doc(hidden)] pub query_type: QueryT,
|
||||
#[doc(hidden)] pub query_info: QueryT::TypeInfo,
|
||||
#[doc(hidden)] pub mutation_type: MutationT,
|
||||
#[doc(hidden)] pub mutation_info: MutationT::TypeInfo,
|
||||
#[doc(hidden)] pub schema: SchemaType<'a>,
|
||||
#[doc(hidden)]
|
||||
pub query_type: QueryT,
|
||||
#[doc(hidden)]
|
||||
pub query_info: QueryT::TypeInfo,
|
||||
#[doc(hidden)]
|
||||
pub mutation_type: MutationT,
|
||||
#[doc(hidden)]
|
||||
pub mutation_info: MutationT::TypeInfo,
|
||||
#[doc(hidden)]
|
||||
pub schema: SchemaType<'a>,
|
||||
}
|
||||
|
||||
/// Metadata for a schema
|
||||
|
@ -50,9 +55,12 @@ pub enum DirectiveLocation {
|
|||
Query,
|
||||
Mutation,
|
||||
Field,
|
||||
#[graphql(name = "FRAGMENT_DEFINITION")] FragmentDefinition,
|
||||
#[graphql(name = "FRAGMENT_SPREAD")] FragmentSpread,
|
||||
#[graphql(name = "INLINE_SPREAD")] InlineFragment,
|
||||
#[graphql(name = "FRAGMENT_DEFINITION")]
|
||||
FragmentDefinition,
|
||||
#[graphql(name = "FRAGMENT_SPREAD")]
|
||||
FragmentSpread,
|
||||
#[graphql(name = "INLINE_SPREAD")]
|
||||
InlineFragment,
|
||||
}
|
||||
|
||||
impl<'a, QueryT, MutationT> RootNode<'a, QueryT, MutationT>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use types::base::{Arguments, GraphQLType, TypeKind};
|
||||
use executor::{ExecutionResult, Executor, Registry};
|
||||
use types::base::{Arguments, GraphQLType, TypeKind};
|
||||
|
||||
use schema::meta::{Argument, EnumMeta, EnumValue, Field, InputObjectMeta, InterfaceMeta, MetaType,
|
||||
ObjectMeta, UnionMeta};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use executor::Variables;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use tests::model::Database;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
#[test]
|
||||
fn test_query_type_name() {
|
||||
|
@ -23,24 +23,18 @@ fn test_query_type_name() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"__schema",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"queryType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Query"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"__schema",
|
||||
Value::object(
|
||||
vec![(
|
||||
"queryType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Query"))].into_iter().collect(),
|
||||
),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -63,12 +57,10 @@ fn test_specific_type_name() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"__type",
|
||||
Value::object(vec![("name", Value::string("Droid"))].into_iter().collect()),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"__type",
|
||||
Value::object(vec![("name", Value::string("Droid"))].into_iter().collect()),
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -93,18 +85,16 @@ fn test_specific_object_type_name_and_kind() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"__type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Droid")),
|
||||
("kind", Value::string("OBJECT")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"__type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Droid")),
|
||||
("kind", Value::string("OBJECT")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -129,18 +119,16 @@ fn test_specific_interface_type_name_and_kind() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"__type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Character")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"__type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Character")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -165,23 +153,19 @@ fn test_documentation() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"__type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Droid")),
|
||||
(
|
||||
"description",
|
||||
Value::string(
|
||||
"A mechanical creature in the Star Wars universe.",
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"__type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Droid")),
|
||||
(
|
||||
"description",
|
||||
Value::string("A mechanical creature in the Star Wars universe."),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//! Library tests and fixtures
|
||||
|
||||
pub mod model;
|
||||
mod schema;
|
||||
#[cfg(test)]
|
||||
mod query_tests;
|
||||
#[cfg(test)]
|
||||
mod introspection_tests;
|
||||
pub mod model;
|
||||
#[cfg(test)]
|
||||
mod query_tests;
|
||||
mod schema;
|
||||
#[cfg(test)]
|
||||
mod type_info_tests;
|
||||
|
|
|
@ -5,7 +5,8 @@ use std::collections::HashMap;
|
|||
#[derive(GraphQLEnum, Copy, Clone, Eq, PartialEq, Debug)]
|
||||
#[graphql(_internal)]
|
||||
pub enum Episode {
|
||||
#[graphql(name = "NEW_HOPE")] NewHope,
|
||||
#[graphql(name = "NEW_HOPE")]
|
||||
NewHope,
|
||||
Empire,
|
||||
Jedi,
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use ast::InputValue;
|
||||
use executor::Variables;
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use tests::model::Database;
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
#[test]
|
||||
fn test_hero_name() {
|
||||
|
@ -20,12 +20,10 @@ fn test_hero_name() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"hero",
|
||||
Value::object(vec![("name", Value::string("R2-D2"))].into_iter().collect()),
|
||||
),
|
||||
].into_iter()
|
||||
vec![(
|
||||
"hero",
|
||||
Value::object(vec![("name", Value::string("R2-D2"))].into_iter().collect()),
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -49,18 +47,16 @@ fn test_hero_field_order() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("id", Value::string("2001")),
|
||||
("name", Value::string("R2-D2")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("id", Value::string("2001")),
|
||||
("name", Value::string("R2-D2")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -78,18 +74,16 @@ fn test_hero_field_order() {
|
|||
::execute(doc_reversed, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("R2-D2")),
|
||||
("id", Value::string("2001")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("R2-D2")),
|
||||
("id", Value::string("2001")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -116,38 +110,36 @@ fn test_hero_name_and_friends() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("id", Value::string("2001")),
|
||||
("name", Value::string("R2-D2")),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![("name", Value::string("Luke Skywalker"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("Han Solo"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("Leia Organa"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("id", Value::string("2001")),
|
||||
("name", Value::string("R2-D2")),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![("name", Value::string("Luke Skywalker"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("Han Solo"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("Leia Organa"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -178,153 +170,141 @@ fn test_hero_name_and_friends_and_friends_of_friends() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("id", Value::string("2001")),
|
||||
("name", Value::string("R2-D2")),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Luke Skywalker")),
|
||||
(
|
||||
"appearsIn",
|
||||
Value::list(vec![
|
||||
Value::string("NEW_HOPE"),
|
||||
Value::string("EMPIRE"),
|
||||
Value::string("JEDI"),
|
||||
]),
|
||||
),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Han Solo")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"name",
|
||||
Value::string("Leia Organa"),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("C-3PO"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("R2-D2"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Han Solo")),
|
||||
(
|
||||
"appearsIn",
|
||||
Value::list(vec![
|
||||
Value::string("NEW_HOPE"),
|
||||
Value::string("EMPIRE"),
|
||||
Value::string("JEDI"),
|
||||
]),
|
||||
),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"name",
|
||||
Value::string("Luke Skywalker"),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"name",
|
||||
Value::string("Leia Organa"),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("R2-D2"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Leia Organa")),
|
||||
(
|
||||
"appearsIn",
|
||||
Value::list(vec![
|
||||
Value::string("NEW_HOPE"),
|
||||
Value::string("EMPIRE"),
|
||||
Value::string("JEDI"),
|
||||
]),
|
||||
),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"name",
|
||||
Value::string("Luke Skywalker"),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Han Solo")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("C-3PO"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("R2-D2"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("id", Value::string("2001")),
|
||||
("name", Value::string("R2-D2")),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Luke Skywalker")),
|
||||
(
|
||||
"appearsIn",
|
||||
Value::list(vec![
|
||||
Value::string("NEW_HOPE"),
|
||||
Value::string("EMPIRE"),
|
||||
Value::string("JEDI"),
|
||||
]),
|
||||
),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![("name", Value::string("Han Solo"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![(
|
||||
"name",
|
||||
Value::string("Leia Organa"),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("C-3PO"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("R2-D2"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Han Solo")),
|
||||
(
|
||||
"appearsIn",
|
||||
Value::list(vec![
|
||||
Value::string("NEW_HOPE"),
|
||||
Value::string("EMPIRE"),
|
||||
Value::string("JEDI"),
|
||||
]),
|
||||
),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![(
|
||||
"name",
|
||||
Value::string("Luke Skywalker"),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![(
|
||||
"name",
|
||||
Value::string("Leia Organa"),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("R2-D2"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Leia Organa")),
|
||||
(
|
||||
"appearsIn",
|
||||
Value::list(vec![
|
||||
Value::string("NEW_HOPE"),
|
||||
Value::string("EMPIRE"),
|
||||
Value::string("JEDI"),
|
||||
]),
|
||||
),
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![(
|
||||
"name",
|
||||
Value::string("Luke Skywalker"),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("Han Solo"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("C-3PO"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("R2-D2"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -342,16 +322,14 @@ fn test_query_name() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"human",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Luke Skywalker"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"human",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Luke Skywalker"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -369,16 +347,14 @@ fn test_query_alias_single() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"luke",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Luke Skywalker"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"luke",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Luke Skywalker"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -487,16 +463,14 @@ fn test_query_name_variable() {
|
|||
::execute(doc, None, &schema, &vars, &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"human",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Luke Skywalker"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"human",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Luke Skywalker"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -533,41 +507,33 @@ fn test_query_friends_names() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"human",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![("name", Value::string("Han Solo"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("Leia Organa"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("C-3PO"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("R2-D2"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
vec![(
|
||||
"human",
|
||||
Value::object(
|
||||
vec![(
|
||||
"friends",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![("name", Value::string("Han Solo"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("Leia Organa"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("C-3PO"))].into_iter().collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![("name", Value::string("R2-D2"))].into_iter().collect(),
|
||||
),
|
||||
]),
|
||||
)].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -596,19 +562,17 @@ fn test_query_inline_fragments_droid() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("R2-D2")),
|
||||
("__typename", Value::string("Droid")),
|
||||
("primaryFunction", Value::string("Astromech")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("R2-D2")),
|
||||
("__typename", Value::string("Droid")),
|
||||
("primaryFunction", Value::string("Astromech")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -633,18 +597,16 @@ fn test_query_inline_fragments_human() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Luke Skywalker")),
|
||||
("__typename", Value::string("Human")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"hero",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Luke Skywalker")),
|
||||
("__typename", Value::string("Human")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
@ -667,16 +629,14 @@ fn test_object_typename() {
|
|||
::execute(doc, None, &schema, &Variables::new(), &database),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"human",
|
||||
Value::object(
|
||||
vec![("__typename", Value::string("Human"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
vec![(
|
||||
"human",
|
||||
Value::object(
|
||||
vec![("__typename", Value::string("Human"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
].into_iter()
|
||||
)].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use tests::model::{Character, Database, Droid, Episode, Human};
|
||||
use executor::Context;
|
||||
use tests::model::{Character, Database, Droid, Episode, Human};
|
||||
|
||||
impl Context for Database {}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use indexmap::IndexMap;
|
||||
|
||||
use executor::{ExecutionResult, Executor, Registry, Variables};
|
||||
use value::Value;
|
||||
use schema::meta::MetaType;
|
||||
use schema::model::RootNode;
|
||||
use types::base::{Arguments, GraphQLType};
|
||||
use types::scalars::EmptyMutation;
|
||||
use value::Value;
|
||||
|
||||
pub struct NodeTypeInfo {
|
||||
name: String,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use indexmap::IndexMap;
|
||||
use indexmap::map::Entry;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use ast::{Directive, FromInputValue, InputValue, Selection};
|
||||
use executor::Variables;
|
||||
use value::Value;
|
||||
|
||||
use schema::meta::{Argument, MetaType};
|
||||
use executor::{ExecutionResult, Executor, Registry};
|
||||
use parser::Spanning;
|
||||
use schema::meta::{Argument, MetaType};
|
||||
|
||||
/// GraphQL type kind
|
||||
///
|
||||
|
@ -374,7 +374,7 @@ where
|
|||
|
||||
let sub_exec = executor.field_sub_executor(
|
||||
response_name,
|
||||
&f.name.item,
|
||||
f.name.item,
|
||||
start_pos.clone(),
|
||||
f.selection_set.as_ref().map(|v| &v[..]),
|
||||
);
|
||||
|
@ -505,29 +505,28 @@ fn is_excluded(directives: &Option<Vec<Spanning<Directive>>>, vars: &Variables)
|
|||
|
||||
fn merge_key_into(result: &mut IndexMap<String, Value>, response_name: &str, value: Value) {
|
||||
match result.entry(response_name.to_owned()) {
|
||||
Entry::Occupied(mut e) => {
|
||||
match e.get_mut() {
|
||||
&mut Value::Object(ref mut dest_obj) => {
|
||||
if let Value::Object(src_obj) = value {
|
||||
merge_maps(dest_obj, src_obj);
|
||||
}
|
||||
},
|
||||
&mut Value::List(ref mut dest_list) => {
|
||||
if let Value::List(src_list) = value {
|
||||
dest_list.iter_mut().zip(src_list.into_iter()).for_each(|(d, s)| {
|
||||
match d {
|
||||
&mut Value::Object(ref mut d_obj) => {
|
||||
if let Value::Object(s_obj) = s {
|
||||
merge_maps(d_obj, s_obj);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
Entry::Occupied(mut e) => match e.get_mut() {
|
||||
&mut Value::Object(ref mut dest_obj) => {
|
||||
if let Value::Object(src_obj) = value {
|
||||
merge_maps(dest_obj, src_obj);
|
||||
}
|
||||
}
|
||||
&mut Value::List(ref mut dest_list) => {
|
||||
if let Value::List(src_list) = value {
|
||||
dest_list
|
||||
.iter_mut()
|
||||
.zip(src_list.into_iter())
|
||||
.for_each(|(d, s)| match d {
|
||||
&mut Value::Object(ref mut d_obj) => {
|
||||
if let Value::Object(s_obj) = s {
|
||||
merge_maps(d_obj, s_obj);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Entry::Vacant(e) => {
|
||||
e.insert(value);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ast::{FromInputValue, InputValue, Selection, ToInputValue};
|
||||
use value::Value;
|
||||
use schema::meta::MetaType;
|
||||
use value::Value;
|
||||
|
||||
use executor::{Executor, Registry};
|
||||
use types::base::GraphQLType;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
pub mod base;
|
||||
pub mod scalars;
|
||||
pub mod pointers;
|
||||
pub mod containers;
|
||||
pub mod utilities;
|
||||
pub mod name;
|
||||
pub mod pointers;
|
||||
pub mod scalars;
|
||||
pub mod utilities;
|
||||
|
|
|
@ -30,7 +30,7 @@ impl Name {
|
|||
}
|
||||
}
|
||||
}
|
||||
return input.len() > 0;
|
||||
return !input.is_empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use ast::{FromInputValue, InputValue, Selection, ToInputValue};
|
||||
use value::Value;
|
||||
|
||||
use schema::meta::MetaType;
|
||||
use executor::{ExecutionResult, Executor, Registry};
|
||||
use schema::meta::MetaType;
|
||||
use types::base::{Arguments, GraphQLType};
|
||||
|
||||
impl<T, CtxT> GraphQLType for Box<T>
|
||||
|
|
|
@ -113,7 +113,7 @@ graphql_scalar!(f64 as "Float" {
|
|||
|
||||
from_input_value(v: &InputValue) -> Option<f64> {
|
||||
match *v {
|
||||
InputValue::Int(i) => Some(i as f64),
|
||||
InputValue::Int(i) => Some(f64::from(i)),
|
||||
InputValue::Float(f) => Some(f),
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::HashSet;
|
||||
use ast::InputValue;
|
||||
use schema::model::{SchemaType, TypeType};
|
||||
use schema::meta::{EnumMeta, InputObjectMeta, MetaType};
|
||||
use schema::model::{SchemaType, TypeType};
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub fn is_valid_literal_value(
|
||||
schema: &SchemaType,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::collections::HashSet;
|
||||
use std::fmt;
|
||||
|
||||
use parser::SourcePosition;
|
||||
use ast::{Definition, Document, InputValue, VariableDefinitions};
|
||||
use executor::Variables;
|
||||
use validation::RuleError;
|
||||
use schema::model::{SchemaType, TypeType};
|
||||
use parser::SourcePosition;
|
||||
use schema::meta::{EnumMeta, InputObjectMeta, MetaType, ScalarMeta};
|
||||
use schema::model::{SchemaType, TypeType};
|
||||
use validation::RuleError;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Path<'a> {
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
//! Query validation related methods and data structures
|
||||
|
||||
mod visitor;
|
||||
mod traits;
|
||||
mod context;
|
||||
mod input_value;
|
||||
mod multi_visitor;
|
||||
mod rules;
|
||||
mod input_value;
|
||||
mod traits;
|
||||
mod visitor;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_harness;
|
||||
|
||||
pub use self::context::{RuleError, ValidatorContext};
|
||||
pub use self::input_value::validate_input_values;
|
||||
pub use self::multi_visitor::{MultiVisitor, MultiVisitorNil};
|
||||
pub use self::rules::visit_all_rules;
|
||||
pub use self::traits::Visitor;
|
||||
pub use self::visitor::visit;
|
||||
pub use self::context::{RuleError, ValidatorContext};
|
||||
pub use self::rules::visit_all_rules;
|
||||
pub use self::multi_visitor::{MultiVisitor, MultiVisitorNil};
|
||||
pub use self::input_value::validate_input_values;
|
||||
|
||||
#[cfg(test)]
|
||||
pub use self::test_harness::{expect_fails_rule, expect_fails_rule_with_schema, expect_passes_rule,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ast::{Directive, Field, InputValue};
|
||||
use parser::Spanning;
|
||||
use schema::meta::Argument;
|
||||
use types::utilities::is_valid_literal_value;
|
||||
use parser::Spanning;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct ArgumentsOfCorrectType<'a> {
|
||||
|
@ -96,12 +96,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("nonNullIntArg", "Int!"),
|
||||
&[SourcePosition::new(97, 3, 50)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("nonNullIntArg", "Int!"),
|
||||
&[SourcePosition::new(97, 3, 50)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -228,12 +226,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringArg", "String"),
|
||||
&[SourcePosition::new(89, 3, 42)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringArg", "String"),
|
||||
&[SourcePosition::new(89, 3, 42)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -248,12 +244,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringArg", "String"),
|
||||
&[SourcePosition::new(89, 3, 42)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringArg", "String"),
|
||||
&[SourcePosition::new(89, 3, 42)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -268,12 +262,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringArg", "String"),
|
||||
&[SourcePosition::new(89, 3, 42)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringArg", "String"),
|
||||
&[SourcePosition::new(89, 3, 42)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -288,12 +280,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringArg", "String"),
|
||||
&[SourcePosition::new(89, 3, 42)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringArg", "String"),
|
||||
&[SourcePosition::new(89, 3, 42)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -308,12 +298,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("intArg", "Int"),
|
||||
&[SourcePosition::new(83, 3, 36)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("intArg", "Int"),
|
||||
&[SourcePosition::new(83, 3, 36)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -328,12 +316,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("intArg", "Int"),
|
||||
&[SourcePosition::new(83, 3, 36)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("intArg", "Int"),
|
||||
&[SourcePosition::new(83, 3, 36)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -348,12 +334,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("intArg", "Int"),
|
||||
&[SourcePosition::new(83, 3, 36)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("intArg", "Int"),
|
||||
&[SourcePosition::new(83, 3, 36)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -368,12 +352,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("intArg", "Int"),
|
||||
&[SourcePosition::new(83, 3, 36)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("intArg", "Int"),
|
||||
&[SourcePosition::new(83, 3, 36)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -388,12 +370,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("floatArg", "Float"),
|
||||
&[SourcePosition::new(87, 3, 40)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("floatArg", "Float"),
|
||||
&[SourcePosition::new(87, 3, 40)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -408,12 +388,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("floatArg", "Float"),
|
||||
&[SourcePosition::new(87, 3, 40)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("floatArg", "Float"),
|
||||
&[SourcePosition::new(87, 3, 40)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -428,12 +406,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("floatArg", "Float"),
|
||||
&[SourcePosition::new(87, 3, 40)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("floatArg", "Float"),
|
||||
&[SourcePosition::new(87, 3, 40)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -448,12 +424,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("booleanArg", "Boolean"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("booleanArg", "Boolean"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -468,12 +442,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("booleanArg", "Boolean"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("booleanArg", "Boolean"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -488,12 +460,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("booleanArg", "Boolean"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("booleanArg", "Boolean"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -508,12 +478,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("booleanArg", "Boolean"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("booleanArg", "Boolean"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -528,12 +496,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("idArg", "ID"),
|
||||
&[SourcePosition::new(81, 3, 34)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("idArg", "ID"),
|
||||
&[SourcePosition::new(81, 3, 34)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -548,12 +514,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("idArg", "ID"),
|
||||
&[SourcePosition::new(81, 3, 34)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("idArg", "ID"),
|
||||
&[SourcePosition::new(81, 3, 34)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -568,12 +532,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("idArg", "ID"),
|
||||
&[SourcePosition::new(81, 3, 34)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("idArg", "ID"),
|
||||
&[SourcePosition::new(81, 3, 34)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -588,12 +550,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -608,12 +568,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -628,12 +586,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -648,12 +604,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -668,12 +622,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -688,12 +640,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("dogCommand", "DogCommand"),
|
||||
&[SourcePosition::new(79, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -750,12 +700,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringListArg", "[String]"),
|
||||
&[SourcePosition::new(97, 3, 50)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringListArg", "[String]"),
|
||||
&[SourcePosition::new(97, 3, 50)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -770,12 +718,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringListArg", "[String]"),
|
||||
&[SourcePosition::new(97, 3, 50)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringListArg", "[String]"),
|
||||
&[SourcePosition::new(97, 3, 50)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -954,12 +900,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("req1", "Int!"),
|
||||
&[SourcePosition::new(82, 3, 35)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("req1", "Int!"),
|
||||
&[SourcePosition::new(82, 3, 35)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1070,12 +1014,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("complexArg", "ComplexInput"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("complexArg", "ComplexInput"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1093,12 +1035,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("complexArg", "ComplexInput"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("complexArg", "ComplexInput"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1116,12 +1056,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("complexArg", "ComplexInput"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("complexArg", "ComplexInput"),
|
||||
&[SourcePosition::new(91, 3, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ast::VariableDefinition;
|
||||
use types::utilities::is_valid_literal_value;
|
||||
use parser::Spanning;
|
||||
use types::utilities::is_valid_literal_value;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct DefaultValuesOfCorrectType {}
|
||||
|
@ -162,12 +162,10 @@ mod tests {
|
|||
dog { name }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&type_error_message("a", "ComplexInput"),
|
||||
&[SourcePosition::new(57, 1, 56)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&type_error_message("a", "ComplexInput"),
|
||||
&[SourcePosition::new(57, 1, 56)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -180,12 +178,10 @@ mod tests {
|
|||
dog { name }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&type_error_message("a", "[String]"),
|
||||
&[SourcePosition::new(44, 1, 43)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&type_error_message("a", "[String]"),
|
||||
&[SourcePosition::new(44, 1, 43)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ast::Field;
|
||||
use parser::Spanning;
|
||||
use schema::meta::MetaType;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
|
||||
pub struct FieldsOnCorrectType {}
|
||||
|
||||
|
@ -160,12 +160,10 @@ mod tests {
|
|||
meowVolume
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("meowVolume", "Dog"),
|
||||
&[SourcePosition::new(57, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("meowVolume", "Dog"),
|
||||
&[SourcePosition::new(57, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -180,12 +178,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("unknown_field", "Dog"),
|
||||
&[SourcePosition::new(61, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("unknown_field", "Dog"),
|
||||
&[SourcePosition::new(61, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -200,12 +196,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("unknown_field", "Pet"),
|
||||
&[SourcePosition::new(83, 3, 14)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("unknown_field", "Pet"),
|
||||
&[SourcePosition::new(83, 3, 14)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -220,12 +214,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("meowVolume", "Dog"),
|
||||
&[SourcePosition::new(84, 3, 14)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("meowVolume", "Dog"),
|
||||
&[SourcePosition::new(84, 3, 14)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -238,12 +230,10 @@ mod tests {
|
|||
volume : mooVolume
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("mooVolume", "Dog"),
|
||||
&[SourcePosition::new(79, 2, 21)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("mooVolume", "Dog"),
|
||||
&[SourcePosition::new(79, 2, 21)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -256,12 +246,10 @@ mod tests {
|
|||
barkVolume : kawVolume
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("kawVolume", "Dog"),
|
||||
&[SourcePosition::new(88, 2, 25)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("kawVolume", "Dog"),
|
||||
&[SourcePosition::new(88, 2, 25)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -274,12 +262,10 @@ mod tests {
|
|||
tailLength
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("tailLength", "Pet"),
|
||||
&[SourcePosition::new(63, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("tailLength", "Pet"),
|
||||
&[SourcePosition::new(63, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -292,12 +278,10 @@ mod tests {
|
|||
nickname
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("nickname", "Pet"),
|
||||
&[SourcePosition::new(78, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("nickname", "Pet"),
|
||||
&[SourcePosition::new(78, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -322,12 +306,10 @@ mod tests {
|
|||
name
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("name", "CatOrDog"),
|
||||
&[SourcePosition::new(82, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("name", "CatOrDog"),
|
||||
&[SourcePosition::new(82, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -145,12 +145,10 @@ mod tests {
|
|||
bad
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("scalarFragment"), "Boolean"),
|
||||
&[SourcePosition::new(38, 1, 37)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("scalarFragment"), "Boolean"),
|
||||
&[SourcePosition::new(38, 1, 37)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -163,12 +161,10 @@ mod tests {
|
|||
bad
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("scalarFragment"), "FurColor"),
|
||||
&[SourcePosition::new(38, 1, 37)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("scalarFragment"), "FurColor"),
|
||||
&[SourcePosition::new(38, 1, 37)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -181,12 +177,10 @@ mod tests {
|
|||
stringField
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("inputFragment"), "ComplexInput"),
|
||||
&[SourcePosition::new(37, 1, 36)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("inputFragment"), "ComplexInput"),
|
||||
&[SourcePosition::new(37, 1, 36)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -201,12 +195,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(None, "String"),
|
||||
&[SourcePosition::new(64, 2, 19)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(None, "String"),
|
||||
&[SourcePosition::new(64, 2, 19)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ast::{Directive, Field, InputValue};
|
||||
use schema::meta::Argument;
|
||||
use parser::Spanning;
|
||||
use schema::meta::Argument;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -204,12 +204,10 @@ mod tests {
|
|||
dog @skip(unless: true)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&directive_error_message("unless", "skip"),
|
||||
&[SourcePosition::new(35, 2, 22)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&directive_error_message("unless", "skip"),
|
||||
&[SourcePosition::new(35, 2, 22)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -222,12 +220,10 @@ mod tests {
|
|||
doesKnowCommand(unknown: true)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&field_error_message("unknown", "doesKnowCommand", "Dog"),
|
||||
&[SourcePosition::new(72, 2, 28)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&field_error_message("unknown", "doesKnowCommand", "Dog"),
|
||||
&[SourcePosition::new(72, 2, 28)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ast::{Directive, Field, Fragment, FragmentSpread, InlineFragment, Operation, OperationType};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use schema::model::DirectiveLocation;
|
||||
use parser::Spanning;
|
||||
use schema::model::DirectiveLocation;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct KnownDirectives {
|
||||
location_stack: Vec<DirectiveLocation>,
|
||||
|
@ -141,8 +141,8 @@ mod tests {
|
|||
use super::{factory, misplaced_error_message, unknown_error_message};
|
||||
|
||||
use parser::SourcePosition;
|
||||
use validation::{expect_fails_rule, expect_passes_rule, RuleError};
|
||||
use schema::model::DirectiveLocation;
|
||||
use validation::{expect_fails_rule, expect_passes_rule, RuleError};
|
||||
|
||||
#[test]
|
||||
fn with_no_directives() {
|
||||
|
@ -189,12 +189,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&unknown_error_message("unknown"),
|
||||
&[SourcePosition::new(29, 2, 16)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&unknown_error_message("unknown"),
|
||||
&[SourcePosition::new(29, 2, 16)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ast::FragmentSpread;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct KnownFragmentNames {}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ast::{Fragment, InlineFragment, VariableDefinition};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::{SourcePosition, Spanning};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct KnownTypeNames {}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ast::{Definition, Document, Operation};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct LoneAnonymousOperation {
|
||||
operation_count: Option<usize>,
|
||||
|
@ -134,9 +134,10 @@ mod tests {
|
|||
fieldB
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(error_message(), &[SourcePosition::new(11, 1, 10)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
error_message(),
|
||||
&[SourcePosition::new(11, 1, 10)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use ast::{Document, Fragment, FragmentSpread};
|
||||
use validation::{RuleError, ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
use validation::{RuleError, ValidatorContext, Visitor};
|
||||
|
||||
pub struct NoFragmentCycles<'a> {
|
||||
current_fragment: Option<&'a str>,
|
||||
|
@ -203,9 +203,10 @@ mod tests {
|
|||
r#"
|
||||
fragment fragA on Human { relatives { ...fragA } },
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(&error_message("fragA"), &[SourcePosition::new(49, 1, 48)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("fragA"),
|
||||
&[SourcePosition::new(49, 1, 48)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -216,9 +217,10 @@ mod tests {
|
|||
r#"
|
||||
fragment fragA on Dog { ...fragA }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(&error_message("fragA"), &[SourcePosition::new(35, 1, 34)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("fragA"),
|
||||
&[SourcePosition::new(35, 1, 34)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -233,9 +235,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(&error_message("fragA"), &[SourcePosition::new(74, 3, 14)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("fragA"),
|
||||
&[SourcePosition::new(74, 3, 14)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -247,9 +250,10 @@ mod tests {
|
|||
fragment fragA on Dog { ...fragB }
|
||||
fragment fragB on Dog { ...fragA }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(&error_message("fragA"), &[SourcePosition::new(35, 1, 34)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("fragA"),
|
||||
&[SourcePosition::new(35, 1, 34)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -261,9 +265,10 @@ mod tests {
|
|||
fragment fragB on Dog { ...fragA }
|
||||
fragment fragA on Dog { ...fragB }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(&error_message("fragB"), &[SourcePosition::new(35, 1, 34)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("fragB"),
|
||||
&[SourcePosition::new(35, 1, 34)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -283,9 +288,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(&error_message("fragA"), &[SourcePosition::new(74, 3, 14)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("fragA"),
|
||||
&[SourcePosition::new(74, 3, 14)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
use ast::{Document, Fragment, FragmentSpread, InputValue, Operation, VariableDefinition};
|
||||
use validation::{RuleError, ValidatorContext, Visitor};
|
||||
use parser::{SourcePosition, Spanning};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use validation::{RuleError, ValidatorContext, Visitor};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Scope<'a> {
|
||||
|
@ -302,15 +302,13 @@ mod tests {
|
|||
field(a: $a, b: $b, c: $c, d: $d)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("d", Some("Foo")),
|
||||
&[
|
||||
SourcePosition::new(101, 2, 42),
|
||||
SourcePosition::new(11, 1, 10),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("d", Some("Foo")),
|
||||
&[
|
||||
SourcePosition::new(101, 2, 42),
|
||||
SourcePosition::new(11, 1, 10),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -323,15 +321,13 @@ mod tests {
|
|||
field(a: $a)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("a", None),
|
||||
&[
|
||||
SourcePosition::new(34, 2, 21),
|
||||
SourcePosition::new(11, 1, 10),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("a", None),
|
||||
&[
|
||||
SourcePosition::new(34, 2, 21),
|
||||
SourcePosition::new(11, 1, 10),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -375,15 +371,13 @@ mod tests {
|
|||
field(a: $a)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("a", None),
|
||||
&[
|
||||
SourcePosition::new(102, 5, 21),
|
||||
SourcePosition::new(11, 1, 10),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("a", None),
|
||||
&[
|
||||
SourcePosition::new(102, 5, 21),
|
||||
SourcePosition::new(11, 1, 10),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -409,15 +403,13 @@ mod tests {
|
|||
field(c: $c)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("c", Some("Foo")),
|
||||
&[
|
||||
SourcePosition::new(358, 15, 21),
|
||||
SourcePosition::new(11, 1, 10),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("c", Some("Foo")),
|
||||
&[
|
||||
SourcePosition::new(358, 15, 21),
|
||||
SourcePosition::new(11, 1, 10),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use ast::{Definition, Document, Fragment, FragmentSpread, Operation};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Scope<'a> {
|
||||
|
@ -270,9 +270,10 @@ mod tests {
|
|||
name
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(&error_message("foo"), &[SourcePosition::new(107, 6, 10)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("foo"),
|
||||
&[SourcePosition::new(107, 6, 10)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
use ast::{Document, Fragment, FragmentSpread, InputValue, Operation, VariableDefinition};
|
||||
use validation::{RuleError, ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use validation::{RuleError, ValidatorContext, Visitor};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Scope<'a> {
|
||||
|
@ -274,9 +274,10 @@ mod tests {
|
|||
field(a: $a, b: $b)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(&error_message("c", None), &[SourcePosition::new(42, 1, 41)]),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("c", None),
|
||||
&[SourcePosition::new(42, 1, 41)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -324,12 +325,10 @@ mod tests {
|
|||
field
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("c", Some("Foo")),
|
||||
&[SourcePosition::new(45, 1, 44)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("c", Some("Foo")),
|
||||
&[SourcePosition::new(45, 1, 44)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -383,12 +382,10 @@ mod tests {
|
|||
field(b: $b)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("b", Some("Foo")),
|
||||
&[SourcePosition::new(21, 1, 20)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("b", Some("Foo")),
|
||||
&[SourcePosition::new(21, 1, 20)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
use std::cell::RefCell;
|
||||
use std::hash::Hash;
|
||||
use std::borrow::Borrow;
|
||||
use ast::{Arguments, Definition, Document, Field, Fragment, FragmentSpread, Selection, Type};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::{SourcePosition, Spanning};
|
||||
use schema::meta::{Field as FieldType, MetaType};
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Conflict(ConflictReason, Vec<SourcePosition>, Vec<SourcePosition>);
|
||||
|
@ -708,13 +708,13 @@ fn format_reason(reason: &ConflictReasonMessage) -> String {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{error_message, factory, ConflictReason};
|
||||
use super::ConflictReasonMessage::*;
|
||||
use super::{error_message, factory, ConflictReason};
|
||||
|
||||
use types::base::GraphQLType;
|
||||
use executor::Registry;
|
||||
use types::scalars::ID;
|
||||
use schema::meta::MetaType;
|
||||
use types::base::GraphQLType;
|
||||
use types::scalars::ID;
|
||||
|
||||
use parser::SourcePosition;
|
||||
use validation::{expect_fails_rule, expect_fails_rule_with_schema, expect_passes_rule,
|
||||
|
@ -821,18 +821,16 @@ mod tests {
|
|||
fido: nickname
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"fido",
|
||||
&Message("name and nickname are different fields".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(78, 2, 12),
|
||||
SourcePosition::new(101, 3, 12),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"fido",
|
||||
&Message("name and nickname are different fields".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(78, 2, 12),
|
||||
SourcePosition::new(101, 3, 12),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -863,18 +861,16 @@ mod tests {
|
|||
name
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"name",
|
||||
&Message("nickname and name are different fields".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(71, 2, 12),
|
||||
SourcePosition::new(98, 3, 12),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"name",
|
||||
&Message("nickname and name are different fields".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(71, 2, 12),
|
||||
SourcePosition::new(98, 3, 12),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -888,18 +884,16 @@ mod tests {
|
|||
doesKnowCommand(dogCommand: HEEL)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"doesKnowCommand",
|
||||
&Message("they have differing arguments".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(57, 2, 12),
|
||||
SourcePosition::new(85, 3, 12),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"doesKnowCommand",
|
||||
&Message("they have differing arguments".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(57, 2, 12),
|
||||
SourcePosition::new(85, 3, 12),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -913,18 +907,16 @@ mod tests {
|
|||
doesKnowCommand
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"doesKnowCommand",
|
||||
&Message("they have differing arguments".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(57, 2, 12),
|
||||
SourcePosition::new(102, 3, 12),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"doesKnowCommand",
|
||||
&Message("they have differing arguments".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(57, 2, 12),
|
||||
SourcePosition::new(102, 3, 12),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -938,18 +930,16 @@ mod tests {
|
|||
doesKnowCommand(dogCommand: HEEL)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"doesKnowCommand",
|
||||
&Message("they have differing arguments".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(57, 2, 12),
|
||||
SourcePosition::new(102, 3, 12),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"doesKnowCommand",
|
||||
&Message("they have differing arguments".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(57, 2, 12),
|
||||
SourcePosition::new(102, 3, 12),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -986,15 +976,13 @@ mod tests {
|
|||
x: b
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("x", &Message("a and b are different fields".to_owned())),
|
||||
&[
|
||||
SourcePosition::new(102, 6, 12),
|
||||
SourcePosition::new(162, 9, 12),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("x", &Message("a and b are different fields".to_owned())),
|
||||
&[
|
||||
SourcePosition::new(102, 6, 12),
|
||||
SourcePosition::new(162, 9, 12),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1065,25 +1053,21 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"field",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(25, 2, 12),
|
||||
SourcePosition::new(47, 3, 14),
|
||||
SourcePosition::new(79, 5, 12),
|
||||
SourcePosition::new(101, 6, 14),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"field",
|
||||
&Nested(vec![ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
)]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(25, 2, 12),
|
||||
SourcePosition::new(47, 3, 14),
|
||||
SourcePosition::new(79, 5, 12),
|
||||
SourcePosition::new(101, 6, 14),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1103,31 +1087,29 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"field",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
),
|
||||
ConflictReason(
|
||||
"y".to_owned(),
|
||||
Message("c and d are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(25, 2, 12),
|
||||
SourcePosition::new(47, 3, 14),
|
||||
SourcePosition::new(66, 4, 14),
|
||||
SourcePosition::new(98, 6, 12),
|
||||
SourcePosition::new(120, 7, 14),
|
||||
SourcePosition::new(139, 8, 14),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"field",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
),
|
||||
ConflictReason(
|
||||
"y".to_owned(),
|
||||
Message("c and d are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(25, 2, 12),
|
||||
SourcePosition::new(47, 3, 14),
|
||||
SourcePosition::new(66, 4, 14),
|
||||
SourcePosition::new(98, 6, 12),
|
||||
SourcePosition::new(120, 7, 14),
|
||||
SourcePosition::new(139, 8, 14),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1149,32 +1131,26 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"field",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"deepField".to_owned(),
|
||||
Nested(vec![
|
||||
ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(25, 2, 12),
|
||||
SourcePosition::new(47, 3, 14),
|
||||
SourcePosition::new(75, 4, 16),
|
||||
SourcePosition::new(123, 7, 12),
|
||||
SourcePosition::new(145, 8, 14),
|
||||
SourcePosition::new(173, 9, 16),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"field",
|
||||
&Nested(vec![ConflictReason(
|
||||
"deepField".to_owned(),
|
||||
Nested(vec![ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
)]),
|
||||
)]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(25, 2, 12),
|
||||
SourcePosition::new(47, 3, 14),
|
||||
SourcePosition::new(75, 4, 16),
|
||||
SourcePosition::new(123, 7, 12),
|
||||
SourcePosition::new(145, 8, 14),
|
||||
SourcePosition::new(173, 9, 16),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1199,25 +1175,21 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"deepField",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(47, 3, 14),
|
||||
SourcePosition::new(75, 4, 16),
|
||||
SourcePosition::new(110, 6, 14),
|
||||
SourcePosition::new(138, 7, 16),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"deepField",
|
||||
&Nested(vec![ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
)]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(47, 3, 14),
|
||||
SourcePosition::new(75, 4, 16),
|
||||
SourcePosition::new(110, 6, 14),
|
||||
SourcePosition::new(138, 7, 16),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1250,25 +1222,21 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"deeperField",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(197, 11, 14),
|
||||
SourcePosition::new(227, 12, 16),
|
||||
SourcePosition::new(262, 14, 14),
|
||||
SourcePosition::new(292, 15, 16),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"deeperField",
|
||||
&Nested(vec![ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
)]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(197, 11, 14),
|
||||
SourcePosition::new(227, 12, 16),
|
||||
SourcePosition::new(262, 14, 14),
|
||||
SourcePosition::new(292, 15, 16),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1300,31 +1268,29 @@ mod tests {
|
|||
x: b
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"field",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
),
|
||||
ConflictReason(
|
||||
"y".to_owned(),
|
||||
Message("c and d are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(25, 2, 12),
|
||||
SourcePosition::new(171, 10, 12),
|
||||
SourcePosition::new(245, 14, 12),
|
||||
SourcePosition::new(78, 5, 12),
|
||||
SourcePosition::new(376, 21, 12),
|
||||
SourcePosition::new(302, 17, 12),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"field",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"x".to_owned(),
|
||||
Message("a and b are different fields".to_owned()),
|
||||
),
|
||||
ConflictReason(
|
||||
"y".to_owned(),
|
||||
Message("c and d are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(25, 2, 12),
|
||||
SourcePosition::new(171, 10, 12),
|
||||
SourcePosition::new(245, 14, 12),
|
||||
SourcePosition::new(78, 5, 12),
|
||||
SourcePosition::new(376, 21, 12),
|
||||
SourcePosition::new(302, 17, 12),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1594,18 +1560,16 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"scalar",
|
||||
&Message("they return conflicting types Int and String!".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(88, 4, 18),
|
||||
SourcePosition::new(173, 7, 18),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"scalar",
|
||||
&Message("they return conflicting types Int and String!".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(88, 4, 18),
|
||||
SourcePosition::new(173, 7, 18),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1650,18 +1614,16 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"scalar",
|
||||
&Message("they return conflicting types Int and String".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(89, 4, 18),
|
||||
SourcePosition::new(167, 7, 18),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"scalar",
|
||||
&Message("they return conflicting types Int and String".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(89, 4, 18),
|
||||
SourcePosition::new(167, 7, 18),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1714,27 +1676,21 @@ mod tests {
|
|||
scalar: unrelatedField
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"other",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"scalar".to_owned(),
|
||||
Message(
|
||||
"scalar and unrelatedField are different fields".to_owned(),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(703, 30, 14),
|
||||
SourcePosition::new(889, 38, 14),
|
||||
SourcePosition::new(771, 33, 14),
|
||||
SourcePosition::new(960, 41, 14),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"other",
|
||||
&Nested(vec![ConflictReason(
|
||||
"scalar".to_owned(),
|
||||
Message("scalar and unrelatedField are different fields".to_owned()),
|
||||
)]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(703, 30, 14),
|
||||
SourcePosition::new(889, 38, 14),
|
||||
SourcePosition::new(771, 33, 14),
|
||||
SourcePosition::new(960, 41, 14),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1755,18 +1711,16 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"scalar",
|
||||
&Message("they return conflicting types String! and String".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(100, 4, 18),
|
||||
SourcePosition::new(178, 7, 18),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"scalar",
|
||||
&Message("they return conflicting types String! and String".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(100, 4, 18),
|
||||
SourcePosition::new(178, 7, 18),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1791,20 +1745,16 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"box",
|
||||
&Message(
|
||||
"they return conflicting types [StringBox] and StringBox".to_owned(),
|
||||
),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(89, 4, 18),
|
||||
SourcePosition::new(228, 9, 18),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"box",
|
||||
&Message("they return conflicting types [StringBox] and StringBox".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(89, 4, 18),
|
||||
SourcePosition::new(228, 9, 18),
|
||||
],
|
||||
)],
|
||||
);
|
||||
|
||||
expect_fails_rule_with_schema(
|
||||
|
@ -1826,20 +1776,16 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"box",
|
||||
&Message(
|
||||
"they return conflicting types StringBox and [StringBox]".to_owned(),
|
||||
),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(89, 4, 18),
|
||||
SourcePosition::new(224, 9, 18),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"box",
|
||||
&Message("they return conflicting types StringBox and [StringBox]".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(89, 4, 18),
|
||||
SourcePosition::new(224, 9, 18),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1865,18 +1811,16 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"val",
|
||||
&Message("scalar and unrelatedField are different fields".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(126, 5, 20),
|
||||
SourcePosition::new(158, 6, 20),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"val",
|
||||
&Message("scalar and unrelatedField are different fields".to_owned()),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(126, 5, 20),
|
||||
SourcePosition::new(158, 6, 20),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1901,25 +1845,21 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"box",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"scalar".to_owned(),
|
||||
Message("they return conflicting types String and Int".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(89, 4, 18),
|
||||
SourcePosition::new(126, 5, 20),
|
||||
SourcePosition::new(224, 9, 18),
|
||||
SourcePosition::new(258, 10, 20),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"box",
|
||||
&Nested(vec![ConflictReason(
|
||||
"scalar".to_owned(),
|
||||
Message("they return conflicting types String and Int".to_owned()),
|
||||
)]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(89, 4, 18),
|
||||
SourcePosition::new(126, 5, 20),
|
||||
SourcePosition::new(224, 9, 18),
|
||||
SourcePosition::new(258, 10, 20),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2004,32 +1944,26 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(
|
||||
"edges",
|
||||
&Nested(vec![
|
||||
ConflictReason(
|
||||
"node".to_owned(),
|
||||
Nested(vec![
|
||||
ConflictReason(
|
||||
"id".to_owned(),
|
||||
Message("name and id are different fields".to_owned()),
|
||||
),
|
||||
]),
|
||||
),
|
||||
]),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(84, 4, 16),
|
||||
SourcePosition::new(110, 5, 18),
|
||||
SourcePosition::new(137, 6, 20),
|
||||
SourcePosition::new(273, 13, 14),
|
||||
SourcePosition::new(297, 14, 16),
|
||||
SourcePosition::new(322, 15, 18),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(
|
||||
"edges",
|
||||
&Nested(vec![ConflictReason(
|
||||
"node".to_owned(),
|
||||
Nested(vec![ConflictReason(
|
||||
"id".to_owned(),
|
||||
Message("name and id are different fields".to_owned()),
|
||||
)]),
|
||||
)]),
|
||||
),
|
||||
],
|
||||
&[
|
||||
SourcePosition::new(84, 4, 16),
|
||||
SourcePosition::new(110, 5, 18),
|
||||
SourcePosition::new(137, 6, 20),
|
||||
SourcePosition::new(273, 13, 14),
|
||||
SourcePosition::new(297, 14, 16),
|
||||
SourcePosition::new(322, 15, 18),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::collections::HashMap;
|
||||
use ast::{Definition, Document, FragmentSpread, InlineFragment};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
use schema::meta::MetaType;
|
||||
use std::collections::HashMap;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct PossibleFragmentSpreads<'a> {
|
||||
fragment_types: HashMap<&'a str, &'a MetaType<'a>>,
|
||||
|
@ -223,12 +223,10 @@ mod tests {
|
|||
fragment invalidObjectWithinObject on Cat { ...dogFragment }
|
||||
fragment dogFragment on Dog { barkVolume }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("dogFragment"), "Cat", "Dog"),
|
||||
&[SourcePosition::new(55, 1, 54)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("dogFragment"), "Cat", "Dog"),
|
||||
&[SourcePosition::new(55, 1, 54)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -241,12 +239,10 @@ mod tests {
|
|||
... on Dog { barkVolume }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(None, "Cat", "Dog"),
|
||||
&[SourcePosition::new(71, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(None, "Cat", "Dog"),
|
||||
&[SourcePosition::new(71, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -258,12 +254,10 @@ mod tests {
|
|||
fragment invalidObjectWithinInterface on Pet { ...humanFragment }
|
||||
fragment humanFragment on Human { pets { name } }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("humanFragment"), "Pet", "Human"),
|
||||
&[SourcePosition::new(58, 1, 57)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("humanFragment"), "Pet", "Human"),
|
||||
&[SourcePosition::new(58, 1, 57)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -275,12 +269,10 @@ mod tests {
|
|||
fragment invalidObjectWithinUnion on CatOrDog { ...humanFragment }
|
||||
fragment humanFragment on Human { pets { name } }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("humanFragment"), "CatOrDog", "Human"),
|
||||
&[SourcePosition::new(59, 1, 58)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("humanFragment"), "CatOrDog", "Human"),
|
||||
&[SourcePosition::new(59, 1, 58)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -292,12 +284,10 @@ mod tests {
|
|||
fragment invalidUnionWithinObject on Human { ...catOrDogFragment }
|
||||
fragment catOrDogFragment on CatOrDog { __typename }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("catOrDogFragment"), "Human", "CatOrDog"),
|
||||
&[SourcePosition::new(56, 1, 55)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("catOrDogFragment"), "Human", "CatOrDog"),
|
||||
&[SourcePosition::new(56, 1, 55)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -309,12 +299,10 @@ mod tests {
|
|||
fragment invalidUnionWithinInterface on Pet { ...humanOrAlienFragment }
|
||||
fragment humanOrAlienFragment on HumanOrAlien { __typename }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("humanOrAlienFragment"), "Pet", "HumanOrAlien"),
|
||||
&[SourcePosition::new(57, 1, 56)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("humanOrAlienFragment"), "Pet", "HumanOrAlien"),
|
||||
&[SourcePosition::new(57, 1, 56)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -326,12 +314,10 @@ mod tests {
|
|||
fragment invalidUnionWithinUnion on CatOrDog { ...humanOrAlienFragment }
|
||||
fragment humanOrAlienFragment on HumanOrAlien { __typename }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("humanOrAlienFragment"), "CatOrDog", "HumanOrAlien"),
|
||||
&[SourcePosition::new(58, 1, 57)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("humanOrAlienFragment"), "CatOrDog", "HumanOrAlien"),
|
||||
&[SourcePosition::new(58, 1, 57)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -343,12 +329,10 @@ mod tests {
|
|||
fragment invalidInterfaceWithinObject on Cat { ...intelligentFragment }
|
||||
fragment intelligentFragment on Intelligent { iq }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("intelligentFragment"), "Cat", "Intelligent"),
|
||||
&[SourcePosition::new(58, 1, 57)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("intelligentFragment"), "Cat", "Intelligent"),
|
||||
&[SourcePosition::new(58, 1, 57)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -362,12 +346,10 @@ mod tests {
|
|||
}
|
||||
fragment intelligentFragment on Intelligent { iq }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("intelligentFragment"), "Pet", "Intelligent"),
|
||||
&[SourcePosition::new(73, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("intelligentFragment"), "Pet", "Intelligent"),
|
||||
&[SourcePosition::new(73, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -380,12 +362,10 @@ mod tests {
|
|||
...on Intelligent { iq }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(None, "Pet", "Intelligent"),
|
||||
&[SourcePosition::new(77, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(None, "Pet", "Intelligent"),
|
||||
&[SourcePosition::new(77, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -397,12 +377,10 @@ mod tests {
|
|||
fragment invalidInterfaceWithinUnion on HumanOrAlien { ...petFragment }
|
||||
fragment petFragment on Pet { name }
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message(Some("petFragment"), "HumanOrAlien", "Pet"),
|
||||
&[SourcePosition::new(66, 1, 65)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message(Some("petFragment"), "HumanOrAlien", "Pet"),
|
||||
&[SourcePosition::new(66, 1, 65)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use ast::{Directive, Field};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
use schema::meta::Field as FieldType;
|
||||
use schema::model::DirectiveType;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct ProvidedNonNullArguments {}
|
||||
|
||||
|
@ -262,12 +262,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&field_error_message("multipleReqs", "req1", "Int!"),
|
||||
&[SourcePosition::new(63, 3, 16)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&field_error_message("multipleReqs", "req1", "Int!"),
|
||||
&[SourcePosition::new(63, 3, 16)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -306,12 +304,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&field_error_message("multipleReqs", "req2", "Int!"),
|
||||
&[SourcePosition::new(63, 3, 16)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&field_error_message("multipleReqs", "req2", "Int!"),
|
||||
&[SourcePosition::new(63, 3, 16)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ast::Field;
|
||||
use validation::{RuleError, ValidatorContext, Visitor};
|
||||
use parser::Spanning;
|
||||
use validation::{RuleError, ValidatorContext, Visitor};
|
||||
|
||||
pub struct ScalarLeafs {}
|
||||
|
||||
|
@ -77,12 +77,10 @@ mod tests {
|
|||
human
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&required_error_message("human", "Human"),
|
||||
&[SourcePosition::new(67, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&required_error_message("human", "Human"),
|
||||
&[SourcePosition::new(67, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -95,12 +93,10 @@ mod tests {
|
|||
human { pets }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&required_error_message("pets", "[Pet]"),
|
||||
&[SourcePosition::new(33, 2, 20)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&required_error_message("pets", "[Pet]"),
|
||||
&[SourcePosition::new(33, 2, 20)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -125,12 +121,10 @@ mod tests {
|
|||
barks { sinceWhen }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&no_allowed_error_message("barks", "Boolean"),
|
||||
&[SourcePosition::new(77, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&no_allowed_error_message("barks", "Boolean"),
|
||||
&[SourcePosition::new(77, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -143,12 +137,10 @@ mod tests {
|
|||
furColor { inHexdec }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&no_allowed_error_message("furColor", "FurColor"),
|
||||
&[SourcePosition::new(74, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&no_allowed_error_message("furColor", "FurColor"),
|
||||
&[SourcePosition::new(74, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -161,12 +153,10 @@ mod tests {
|
|||
doesKnowCommand(dogCommand: SIT) { sinceWhen }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&no_allowed_error_message("doesKnowCommand", "Boolean"),
|
||||
&[SourcePosition::new(76, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&no_allowed_error_message("doesKnowCommand", "Boolean"),
|
||||
&[SourcePosition::new(76, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -179,12 +169,10 @@ mod tests {
|
|||
name @include(if: true) { isAlsoHumanName }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&no_allowed_error_message("name", "String"),
|
||||
&[SourcePosition::new(82, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&no_allowed_error_message("name", "String"),
|
||||
&[SourcePosition::new(82, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -197,12 +185,10 @@ mod tests {
|
|||
doesKnowCommand(dogCommand: SIT) @include(if: true) { sinceWhen }
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&no_allowed_error_message("doesKnowCommand", "Boolean"),
|
||||
&[SourcePosition::new(89, 2, 12)],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&no_allowed_error_message("doesKnowCommand", "Boolean"),
|
||||
&[SourcePosition::new(89, 2, 12)],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::collections::hash_map::{Entry, HashMap};
|
||||
|
||||
use ast::{Directive, Field, InputValue};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::{SourcePosition, Spanning};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct UniqueArgumentNames<'a> {
|
||||
known_names: HashMap<&'a str, SourcePosition>,
|
||||
|
@ -171,15 +171,13 @@ mod tests {
|
|||
field(arg1: "value", arg1: "value")
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("arg1"),
|
||||
&[
|
||||
SourcePosition::new(31, 2, 18),
|
||||
SourcePosition::new(46, 2, 33),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("arg1"),
|
||||
&[
|
||||
SourcePosition::new(31, 2, 18),
|
||||
SourcePosition::new(46, 2, 33),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -220,15 +218,13 @@ mod tests {
|
|||
field @directive(arg1: "value", arg1: "value")
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("arg1"),
|
||||
&[
|
||||
SourcePosition::new(42, 2, 29),
|
||||
SourcePosition::new(57, 2, 44),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("arg1"),
|
||||
&[
|
||||
SourcePosition::new(42, 2, 29),
|
||||
SourcePosition::new(57, 2, 44),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -143,15 +143,13 @@ mod tests {
|
|||
fieldB
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&duplicate_message("fragA"),
|
||||
&[
|
||||
SourcePosition::new(65, 4, 19),
|
||||
SourcePosition::new(131, 7, 19),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&duplicate_message("fragA"),
|
||||
&[
|
||||
SourcePosition::new(65, 4, 19),
|
||||
SourcePosition::new(131, 7, 19),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -167,15 +165,13 @@ mod tests {
|
|||
fieldB
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&duplicate_message("fragA"),
|
||||
&[
|
||||
SourcePosition::new(20, 1, 19),
|
||||
SourcePosition::new(86, 4, 19),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&duplicate_message("fragA"),
|
||||
&[
|
||||
SourcePosition::new(20, 1, 19),
|
||||
SourcePosition::new(86, 4, 19),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::collections::hash_map::{Entry, HashMap};
|
||||
|
||||
use ast::InputValue;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
use parser::{SourcePosition, Spanning};
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
pub struct UniqueInputFieldNames<'a> {
|
||||
known_name_stack: Vec<HashMap<&'a str, SourcePosition>>,
|
||||
|
@ -128,15 +128,13 @@ mod tests {
|
|||
field(arg: { f1: "value", f1: "value" })
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("f1"),
|
||||
&[
|
||||
SourcePosition::new(38, 2, 25),
|
||||
SourcePosition::new(51, 2, 38),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("f1"),
|
||||
&[
|
||||
SourcePosition::new(38, 2, 25),
|
||||
SourcePosition::new(51, 2, 38),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -142,15 +142,13 @@ mod tests {
|
|||
fieldB
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("Foo"),
|
||||
&[
|
||||
SourcePosition::new(11, 1, 10),
|
||||
SourcePosition::new(64, 4, 10),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("Foo"),
|
||||
&[
|
||||
SourcePosition::new(11, 1, 10),
|
||||
SourcePosition::new(64, 4, 10),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -166,15 +164,13 @@ mod tests {
|
|||
fieldB
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("Foo"),
|
||||
&[
|
||||
SourcePosition::new(11, 1, 10),
|
||||
SourcePosition::new(64, 4, 10),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("Foo"),
|
||||
&[
|
||||
SourcePosition::new(11, 1, 10),
|
||||
SourcePosition::new(64, 4, 10),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,15 +383,13 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("intArg", "Int", "Int!"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(117, 3, 48),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("intArg", "Int", "Int!"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(117, 3, 48),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -410,15 +408,13 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("intArg", "Int", "Int!"),
|
||||
&[
|
||||
SourcePosition::new(154, 5, 22),
|
||||
SourcePosition::new(110, 2, 46),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("intArg", "Int", "Int!"),
|
||||
&[
|
||||
SourcePosition::new(154, 5, 22),
|
||||
SourcePosition::new(110, 2, 46),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -441,15 +437,13 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("intArg", "Int", "Int!"),
|
||||
&[
|
||||
SourcePosition::new(255, 9, 22),
|
||||
SourcePosition::new(211, 6, 46),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("intArg", "Int", "Int!"),
|
||||
&[
|
||||
SourcePosition::new(255, 9, 22),
|
||||
SourcePosition::new(211, 6, 46),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -464,15 +458,13 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringVar", "String", "Boolean"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(117, 3, 42),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringVar", "String", "Boolean"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(117, 3, 42),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -487,15 +479,13 @@ mod tests {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringVar", "String", "[String]"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(123, 3, 48),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringVar", "String", "[String]"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(123, 3, 48),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -508,15 +498,13 @@ mod tests {
|
|||
dog @include(if: $boolVar)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("boolVar", "Boolean", "Boolean!"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(73, 2, 29),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("boolVar", "Boolean", "Boolean!"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(73, 2, 29),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -529,15 +517,13 @@ mod tests {
|
|||
dog @include(if: $stringVar)
|
||||
}
|
||||
"#,
|
||||
&[
|
||||
RuleError::new(
|
||||
&error_message("stringVar", "String", "Boolean!"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(74, 2, 29),
|
||||
],
|
||||
),
|
||||
],
|
||||
&[RuleError::new(
|
||||
&error_message("stringVar", "String", "Boolean!"),
|
||||
&[
|
||||
SourcePosition::new(23, 1, 22),
|
||||
SourcePosition::new(74, 2, 29),
|
||||
],
|
||||
)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use parser::parse_document_source;
|
||||
use ast::{FromInputValue, InputValue};
|
||||
use types::base::GraphQLType;
|
||||
use executor::Registry;
|
||||
use types::scalars::{EmptyMutation, ID};
|
||||
use schema::model::{DirectiveLocation, DirectiveType, RootNode};
|
||||
use parser::parse_document_source;
|
||||
use schema::meta::{EnumValue, MetaType};
|
||||
use schema::model::{DirectiveLocation, DirectiveType, RootNode};
|
||||
use types::base::GraphQLType;
|
||||
use types::scalars::{EmptyMutation, ID};
|
||||
use validation::{visit, MultiVisitor, MultiVisitorNil, RuleError, ValidatorContext, Visitor};
|
||||
|
||||
struct Being;
|
||||
|
@ -60,11 +60,9 @@ impl GraphQLType for Being {
|
|||
}
|
||||
|
||||
fn meta<'r>(i: &(), registry: &mut Registry<'r>) -> MetaType<'r> {
|
||||
let fields = &[
|
||||
registry
|
||||
.field::<Option<String>>("name", i)
|
||||
.argument(registry.arg::<Option<bool>>("surname", i)),
|
||||
];
|
||||
let fields = &[registry
|
||||
.field::<Option<String>>("name", i)
|
||||
.argument(registry.arg::<Option<bool>>("surname", i))];
|
||||
|
||||
registry.build_interface_type::<Self>(i, fields).into_meta()
|
||||
}
|
||||
|
@ -79,11 +77,9 @@ impl GraphQLType for Pet {
|
|||
}
|
||||
|
||||
fn meta<'r>(i: &(), registry: &mut Registry<'r>) -> MetaType<'r> {
|
||||
let fields = &[
|
||||
registry
|
||||
.field::<Option<String>>("name", i)
|
||||
.argument(registry.arg::<Option<bool>>("surname", i)),
|
||||
];
|
||||
let fields = &[registry
|
||||
.field::<Option<String>>("name", i)
|
||||
.argument(registry.arg::<Option<bool>>("surname", i))];
|
||||
|
||||
registry.build_interface_type::<Self>(i, fields).into_meta()
|
||||
}
|
||||
|
@ -98,11 +94,9 @@ impl GraphQLType for Canine {
|
|||
}
|
||||
|
||||
fn meta<'r>(i: &(), registry: &mut Registry<'r>) -> MetaType<'r> {
|
||||
let fields = &[
|
||||
registry
|
||||
.field::<Option<String>>("name", i)
|
||||
.argument(registry.arg::<Option<bool>>("surname", i)),
|
||||
];
|
||||
let fields = &[registry
|
||||
.field::<Option<String>>("name", i)
|
||||
.argument(registry.arg::<Option<bool>>("surname", i))];
|
||||
|
||||
registry.build_interface_type::<Self>(i, fields).into_meta()
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ use std::borrow::Cow;
|
|||
use ast::{Arguments, Definition, Directive, Document, Field, Fragment, FragmentSpread,
|
||||
InlineFragment, InputValue, Operation, OperationType, Selection, Type,
|
||||
VariableDefinitions};
|
||||
use schema::meta::Argument;
|
||||
use parser::Spanning;
|
||||
use schema::meta::Argument;
|
||||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use indexmap::IndexMap;
|
||||
use std::hash::Hash;
|
||||
|
||||
use parser::Spanning;
|
||||
use ast::{InputValue, ToInputValue};
|
||||
use parser::Spanning;
|
||||
|
||||
/// Serializable value returned from query and field execution.
|
||||
///
|
||||
|
@ -13,7 +13,7 @@ use ast::{InputValue, ToInputValue};
|
|||
/// values or variables. Also, lists and objects do not contain any location
|
||||
/// information since they are generated by resolving fields and values rather
|
||||
/// than parsing a source query.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum Value {
|
||||
Null,
|
||||
|
@ -276,7 +276,7 @@ mod tests {
|
|||
Value::object(
|
||||
vec![("key", Value::int(123)), ("next", Value::boolean(true))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
.collect(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,10 @@ repository = "https://github.com/graphql-rust/juniper"
|
|||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = "0.11"
|
||||
quote = "0.3"
|
||||
syn = { version = "0.13.*", features = ["full", "extra-traits"] }
|
||||
quote = "0.5.*"
|
||||
regex = "0.2.10"
|
||||
lazy_static = "1.0.0"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "graphql-rust/juniper" }
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
use syn;
|
||||
use syn::*;
|
||||
use syn::{
|
||||
DeriveInput,
|
||||
Meta,
|
||||
NestedMeta,
|
||||
Data,
|
||||
Fields,
|
||||
Ident,
|
||||
Variant,
|
||||
};
|
||||
use quote::Tokens;
|
||||
|
||||
use util::*;
|
||||
|
@ -23,16 +31,21 @@ impl EnumAttrs {
|
|||
// Check attributes for name and description.
|
||||
if let Some(items) = get_graphl_attr(&input.attrs) {
|
||||
for item in items {
|
||||
if let Some(val) = keyed_item_value(item, "name", true) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
if let Some(val) = keyed_item_value(&item, "name", true) {
|
||||
if is_valid_name(&*val) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
} else {
|
||||
panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not",
|
||||
&*val);
|
||||
}
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "description", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "description", true) {
|
||||
res.description = Some(val);
|
||||
continue;
|
||||
}
|
||||
match item {
|
||||
&NestedMetaItem::MetaItem(MetaItem::Word(ref ident)) => {
|
||||
NestedMeta::Meta(Meta::Word(ref ident)) => {
|
||||
if ident == "_internal" {
|
||||
res.internal = true;
|
||||
continue;
|
||||
|
@ -64,15 +77,20 @@ impl EnumVariantAttrs {
|
|||
// Check attributes for name and description.
|
||||
if let Some(items) = get_graphl_attr(&variant.attrs) {
|
||||
for item in items {
|
||||
if let Some(val) = keyed_item_value(item, "name", true) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
if let Some(val) = keyed_item_value(&item, "name", true) {
|
||||
if is_valid_name(&*val) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
} else {
|
||||
panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not",
|
||||
&*val);
|
||||
}
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "description", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "description", true) {
|
||||
res.description = Some(val);
|
||||
continue;
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "deprecated", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "deprecated", true) {
|
||||
res.deprecation = Some(val);
|
||||
continue;
|
||||
}
|
||||
|
@ -87,9 +105,9 @@ impl EnumVariantAttrs {
|
|||
}
|
||||
|
||||
pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
|
||||
let variants = match ast.body {
|
||||
Body::Enum(ref var) => var,
|
||||
Body::Struct(_) => {
|
||||
let variants = match ast.data {
|
||||
Data::Enum(ref enum_data) => enum_data.variants.iter().collect::<Vec<_>>(),
|
||||
_ => {
|
||||
panic!("#[derive(GraphlQLEnum)] may only be applied to enums, not to structs");
|
||||
}
|
||||
};
|
||||
|
@ -110,12 +128,16 @@ pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
|
|||
let mut to_inputs = Vec::<Tokens>::new();
|
||||
|
||||
for variant in variants {
|
||||
if variant.data != VariantData::Unit {
|
||||
panic!(format!(
|
||||
"Invalid enum variant {}.\nGraphQL enums may only contain unit variants.",
|
||||
variant.ident
|
||||
));
|
||||
}
|
||||
match variant.fields {
|
||||
Fields::Unit => {},
|
||||
_ => {
|
||||
panic!(format!(
|
||||
"Invalid enum variant {}.\nGraphQL enums may only contain unit variants.",
|
||||
variant.ident
|
||||
));
|
||||
}
|
||||
} ;
|
||||
|
||||
let var_attrs = EnumVariantAttrs::from_input(variant);
|
||||
let var_ident = &variant.ident;
|
||||
|
||||
|
@ -209,7 +231,7 @@ pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
|
|||
}
|
||||
};
|
||||
|
||||
let dummy_const = Ident::new(format!("_IMPL_GRAPHQLENUM_FOR_{}", ident));
|
||||
let dummy_const = Ident::from(format!("_IMPL_GRAPHQLENUM_FOR_{}", ident).as_str());
|
||||
|
||||
// This ugly hack makes it possible to use the derive inside juniper itself.
|
||||
// FIXME: Figure out a better way to do this!
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
use syn;
|
||||
use syn::*;
|
||||
use quote::Tokens;
|
||||
use std::str::FromStr;
|
||||
|
||||
use syn::{
|
||||
self,
|
||||
DeriveInput,
|
||||
NestedMeta,
|
||||
Meta,
|
||||
Field,
|
||||
Fields,
|
||||
Data,
|
||||
Ident,
|
||||
};
|
||||
use quote::{Tokens, ToTokens};
|
||||
|
||||
use util::*;
|
||||
|
||||
|
@ -18,16 +28,21 @@ impl ObjAttrs {
|
|||
// Check attributes for name and description.
|
||||
if let Some(items) = get_graphl_attr(&input.attrs) {
|
||||
for item in items {
|
||||
if let Some(val) = keyed_item_value(item, "name", true) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
if let Some(val) = keyed_item_value(&item, "name", true) {
|
||||
if is_valid_name(&*val) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
} else {
|
||||
panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not",
|
||||
&*val);
|
||||
}
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "description", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "description", true) {
|
||||
res.description = Some(val);
|
||||
continue;
|
||||
}
|
||||
match item {
|
||||
&NestedMetaItem::MetaItem(MetaItem::Word(ref ident)) => {
|
||||
NestedMeta::Meta(Meta::Word(ref ident)) => {
|
||||
if ident == "_internal" {
|
||||
res.internal = true;
|
||||
continue;
|
||||
|
@ -60,20 +75,25 @@ impl ObjFieldAttrs {
|
|||
// Check attributes for name and description.
|
||||
if let Some(items) = get_graphl_attr(&variant.attrs) {
|
||||
for item in items {
|
||||
if let Some(val) = keyed_item_value(item, "name", true) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
if let Some(val) = keyed_item_value(&item, "name", true) {
|
||||
if is_valid_name(&*val) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
} else {
|
||||
panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not",
|
||||
&*val);
|
||||
}
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "description", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "description", true) {
|
||||
res.description = Some(val);
|
||||
continue;
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "default", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "default", true) {
|
||||
res.default_expr = Some(val);
|
||||
continue;
|
||||
}
|
||||
match item {
|
||||
&NestedMetaItem::MetaItem(MetaItem::Word(ref ident)) => {
|
||||
NestedMeta::Meta(Meta::Word(ref ident)) => {
|
||||
if ident == "default" {
|
||||
res.default = true;
|
||||
continue;
|
||||
|
@ -92,16 +112,16 @@ impl ObjFieldAttrs {
|
|||
}
|
||||
|
||||
pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens {
|
||||
let fields = match ast.body {
|
||||
Body::Struct(ref data) => match data {
|
||||
&VariantData::Struct(ref fields) => fields,
|
||||
let fields = match ast.data {
|
||||
Data::Struct(ref data) => match data.fields {
|
||||
Fields::Named(ref named) => named.named.iter().collect::<Vec<_>>(),
|
||||
_ => {
|
||||
panic!(
|
||||
"#[derive(GraphQLInputObject)] may only be used on regular structs with fields"
|
||||
);
|
||||
}
|
||||
},
|
||||
Body::Enum(_) => {
|
||||
_ => {
|
||||
panic!("#[derive(GraphlQLInputObject)] may only be applied to structs, not to enums");
|
||||
}
|
||||
};
|
||||
|
@ -146,8 +166,17 @@ pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens {
|
|||
Some(quote! { Default::default() })
|
||||
} else {
|
||||
match field_attrs.default_expr {
|
||||
Some(ref def) => match syn::parse_token_trees(def) {
|
||||
Ok(t) => Some(quote! { #(#t)* }),
|
||||
Some(ref def) => match ::proc_macro::TokenStream::from_str(def) {
|
||||
Ok(t) => {
|
||||
match syn::parse::<syn::Expr>(t) {
|
||||
Ok(e) => {
|
||||
Some(e.into_tokens())
|
||||
},
|
||||
Err(_) => {
|
||||
panic!("#graphql(default = ?) must be a valid Rust expression inside a string");
|
||||
},
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
panic!("#graphql(default = ?) must be a valid Rust expression inside a string");
|
||||
}
|
||||
|
@ -256,7 +285,7 @@ pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens {
|
|||
}
|
||||
};
|
||||
|
||||
let dummy_const = Ident::new(format!("_IMPL_GRAPHQLINPUTOBJECT_FOR_{}", ident));
|
||||
let dummy_const = Ident::from(format!("_IMPL_GRAPHQLINPUTOBJECT_FOR_{}", ident).as_str());
|
||||
|
||||
// This ugly hack makes it possible to use the derive inside juniper itself.
|
||||
// FIXME: Figure out a better way to do this!
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
use syn;
|
||||
use syn::*;
|
||||
use syn::{
|
||||
DeriveInput,
|
||||
Data,
|
||||
Fields,
|
||||
Field,
|
||||
};
|
||||
use quote::Tokens;
|
||||
|
||||
use util::*;
|
||||
|
@ -17,11 +22,16 @@ impl ObjAttrs {
|
|||
// Check attributes for name and description.
|
||||
if let Some(items) = get_graphl_attr(&input.attrs) {
|
||||
for item in items {
|
||||
if let Some(val) = keyed_item_value(item, "name", true) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
if let Some(val) = keyed_item_value(&item, "name", true) {
|
||||
if is_valid_name(&*val) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
} else {
|
||||
panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not",
|
||||
&*val);
|
||||
}
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "description", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "description", true) {
|
||||
res.description = Some(val);
|
||||
continue;
|
||||
}
|
||||
|
@ -49,15 +59,20 @@ impl ObjFieldAttrs {
|
|||
// Check attributes for name and description.
|
||||
if let Some(items) = get_graphl_attr(&variant.attrs) {
|
||||
for item in items {
|
||||
if let Some(val) = keyed_item_value(item, "name", true) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
if let Some(val) = keyed_item_value(&item, "name", true) {
|
||||
if is_valid_name(&*val) {
|
||||
res.name = Some(val);
|
||||
continue;
|
||||
} else {
|
||||
panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not",
|
||||
&*val);
|
||||
}
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "description", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "description", true) {
|
||||
res.description = Some(val);
|
||||
continue;
|
||||
}
|
||||
if let Some(val) = keyed_item_value(item, "deprecation", true) {
|
||||
if let Some(val) = keyed_item_value(&item, "deprecation", true) {
|
||||
res.deprecation = Some(val);
|
||||
continue;
|
||||
}
|
||||
|
@ -72,14 +87,14 @@ impl ObjFieldAttrs {
|
|||
}
|
||||
|
||||
pub fn impl_object(ast: &syn::DeriveInput) -> Tokens {
|
||||
let fields = match ast.body {
|
||||
Body::Struct(ref data) => match data {
|
||||
&VariantData::Struct(ref fields) => fields,
|
||||
let fields = match ast.data {
|
||||
Data::Struct(ref data) => match data.fields {
|
||||
Fields::Named(ref fields) => fields.named.iter().collect::<Vec<_>>(),
|
||||
_ => {
|
||||
panic!("#[derive(GraphQLObject)] may only be used on regular structs with fields");
|
||||
}
|
||||
},
|
||||
Body::Enum(_) => {
|
||||
_ => {
|
||||
panic!("#[derive(GraphlQLObject)] may only be applied to structs, not to enums");
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,6 +10,9 @@ extern crate proc_macro;
|
|||
#[macro_use]
|
||||
extern crate quote;
|
||||
extern crate syn;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate regex;
|
||||
|
||||
mod util;
|
||||
mod derive_enum;
|
||||
|
@ -20,24 +23,21 @@ use proc_macro::TokenStream;
|
|||
|
||||
#[proc_macro_derive(GraphQLEnum, attributes(graphql))]
|
||||
pub fn derive_enum(input: TokenStream) -> TokenStream {
|
||||
let s = input.to_string();
|
||||
let ast = syn::parse_derive_input(&s).unwrap();
|
||||
let ast = syn::parse::<syn::DeriveInput>(input).unwrap();
|
||||
let gen = derive_enum::impl_enum(&ast);
|
||||
gen.parse().unwrap()
|
||||
gen.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(GraphQLInputObject, attributes(graphql))]
|
||||
pub fn derive_input_object(input: TokenStream) -> TokenStream {
|
||||
let s = input.to_string();
|
||||
let ast = syn::parse_derive_input(&s).unwrap();
|
||||
let ast = syn::parse::<syn::DeriveInput>(input).unwrap();
|
||||
let gen = derive_input_object::impl_input_object(&ast);
|
||||
gen.parse().unwrap()
|
||||
gen.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(GraphQLObject, attributes(graphql))]
|
||||
pub fn derive_object(input: TokenStream) -> TokenStream {
|
||||
let s = input.to_string();
|
||||
let ast = syn::parse_derive_input(&s).unwrap();
|
||||
let ast = syn::parse::<syn::DeriveInput>(input).unwrap();
|
||||
let gen = derive_object::impl_object(&ast);
|
||||
gen.parse().unwrap()
|
||||
gen.into()
|
||||
}
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
use syn::*;
|
||||
use syn::{
|
||||
Attribute,
|
||||
Meta,
|
||||
NestedMeta,
|
||||
Lit,
|
||||
};
|
||||
use regex::Regex;
|
||||
|
||||
pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<&Vec<NestedMetaItem>> {
|
||||
// Get the nested items of a a #[graphql(...)] attribute.
|
||||
pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<Vec<NestedMeta>> {
|
||||
for attr in attrs {
|
||||
match attr.value {
|
||||
MetaItem::List(ref attr_name, ref items) => if attr_name == "graphql" {
|
||||
return Some(items);
|
||||
match attr.interpret_meta() {
|
||||
Some(Meta::List(ref list)) if list.ident == "graphql" => {
|
||||
return Some(list.nested.iter().map(|x| x.clone()).collect());
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
@ -12,33 +19,24 @@ pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<&Vec<NestedMetaItem>> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn keyed_item_value(item: &NestedMetaItem, name: &str, must_be_string: bool) -> Option<String> {
|
||||
let item = match item {
|
||||
&NestedMetaItem::MetaItem(ref item) => item,
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let lit = match item {
|
||||
&MetaItem::NameValue(ref ident, ref lit) => if ident == name {
|
||||
lit
|
||||
} else {
|
||||
return None;
|
||||
},
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
match lit {
|
||||
&Lit::Str(ref val, _) => Some(val.clone()),
|
||||
_ => if must_be_string {
|
||||
panic!(format!(
|
||||
"Invalid format for attribute \"{:?}\": expected a string",
|
||||
item
|
||||
));
|
||||
} else {
|
||||
None
|
||||
pub fn keyed_item_value(item: &NestedMeta, name: &str, must_be_string: bool) -> Option<String> {
|
||||
match item {
|
||||
&NestedMeta::Meta(Meta::NameValue(ref nameval)) if nameval.ident == name => {
|
||||
match &nameval.lit {
|
||||
&Lit::Str(ref strlit) => {
|
||||
Some(strlit.value())
|
||||
},
|
||||
_ => if must_be_string {
|
||||
panic!(format!(
|
||||
"Invalid format for attribute \"{:?}\": expected a string",
|
||||
item
|
||||
));
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,3 +112,24 @@ fn test_to_upper_snake_case() {
|
|||
assert_eq!(to_upper_snake_case("someINpuT"), "SOME_INPU_T");
|
||||
assert_eq!(to_upper_snake_case("some_INpuT"), "SOME_INPU_T");
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn is_valid_name(field_name: &str) -> bool {
|
||||
lazy_static!{
|
||||
static ref GRAPHQL_NAME_SPEC: Regex = Regex::new("^[_A-Za-z][_0-9A-Za-z]*$").unwrap();
|
||||
}
|
||||
GRAPHQL_NAME_SPEC.is_match(field_name)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_valid_name(){
|
||||
assert_eq!(is_valid_name("yesItIs"), true);
|
||||
assert_eq!(is_valid_name("NoitIsnt"), true);
|
||||
assert_eq!(is_valid_name("iso6301"), true);
|
||||
assert_eq!(is_valid_name("thisIsATest"), true);
|
||||
assert_eq!(is_valid_name("i6Op"), true);
|
||||
assert_eq!(is_valid_name("i!"), false);
|
||||
assert_eq!(is_valid_name(""), false);
|
||||
assert_eq!(is_valid_name("aTest"), true);
|
||||
assert_eq!(is_valid_name("__Atest90"), true);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ fn main() {
|
|||
chain.link_before(logger_before);
|
||||
chain.link_after(logger_after);
|
||||
|
||||
let host = env::var("LISTEN").unwrap_or("0.0.0.0:8080".to_owned());
|
||||
let host = env::var("LISTEN").unwrap_or_else(|_| "0.0.0.0:8080".to_owned());
|
||||
println!("GraphQL server started on {}", host);
|
||||
Iron::new(chain).http(host.as_str()).unwrap();
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ use serde_json::error::Error as SerdeError;
|
|||
use juniper::{GraphQLType, InputValue, RootNode};
|
||||
use juniper::http::{self, ExecutionResponse, Executable};
|
||||
|
||||
/// Handler that executes GraphQL queries in the given schema
|
||||
/// Handler that executes `GraphQL` queries in the given schema
|
||||
///
|
||||
/// The handler responds to GET requests and POST requests only. In GET
|
||||
/// requests, the query should be supplied in the `query` URL parameter, e.g.
|
||||
|
@ -146,7 +146,7 @@ where
|
|||
root_node: RootNode<'a, Query, Mutation>,
|
||||
}
|
||||
|
||||
/// Handler that renders GraphiQL - a graphical query editor interface
|
||||
/// Handler that renders `GraphiQL` - a graphical query editor interface
|
||||
pub struct GraphiQLHandler {
|
||||
graphql_url: String,
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ where
|
|||
|
||||
fn handle_get(&self, req: &mut Request) -> IronResult<http::GraphQLBatchRequest> {
|
||||
let url_query_string = req.get_mut::<UrlEncodedQuery>()
|
||||
.map_err(|e| GraphQLIronError::Url(e))?;
|
||||
.map_err(GraphQLIronError::Url)?;
|
||||
|
||||
let input_query = parse_url_param(url_query_string.remove("query"))?
|
||||
.ok_or_else(|| GraphQLIronError::InvalidData("No query provided"))?;
|
||||
|
@ -220,8 +220,8 @@ where
|
|||
itry!(req.body.read_to_string(&mut request_payload));
|
||||
|
||||
Ok(
|
||||
serde_json::from_str::<http::GraphQLBatchRequest>(request_payload.as_str())
|
||||
.map_err(|err| GraphQLIronError::Serde(err))?,
|
||||
serde_json::from_str::<http::GraphQLRequest>(request_payload.as_str())
|
||||
.map_err(GraphQLIronError::Serde)?,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -296,7 +296,7 @@ impl fmt::Display for GraphQLIronError {
|
|||
match *self {
|
||||
GraphQLIronError::Serde(ref err) => fmt::Display::fmt(err, &mut f),
|
||||
GraphQLIronError::Url(ref err) => fmt::Display::fmt(err, &mut f),
|
||||
GraphQLIronError::InvalidData(ref err) => fmt::Display::fmt(err, &mut f),
|
||||
GraphQLIronError::InvalidData(err) => fmt::Display::fmt(err, &mut f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ impl Error for GraphQLIronError {
|
|||
match *self {
|
||||
GraphQLIronError::Serde(ref err) => err.description(),
|
||||
GraphQLIronError::Url(ref err) => err.description(),
|
||||
GraphQLIronError::InvalidData(ref err) => err,
|
||||
GraphQLIronError::InvalidData(err) => err,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ serde_derive = {version="1.0.2" }
|
|||
serde_json = { version = "1.0.2" }
|
||||
juniper = { version = "0.9.2" , path = "../juniper"}
|
||||
|
||||
rocket = { version = "0.3.6" }
|
||||
rocket_codegen = { version = "0.3.6" }
|
||||
rocket = { version = "0.3.9" }
|
||||
rocket_codegen = { version = "0.3.9" }
|
||||
|
||||
[dev-dependencies.juniper]
|
||||
version = "0.9.2"
|
||||
|
|
|
@ -8,8 +8,7 @@ use juniper::{self, FromInputValue, GraphQLType, InputValue, ToInputValue};
|
|||
#[graphql(name = "Some", description = "enum descr")]
|
||||
enum SomeEnum {
|
||||
Regular,
|
||||
|
||||
#[graphql(name = "full", description = "field descr", deprecated = "depr")] Full,
|
||||
#[graphql(name = "FULL", description = "field descr", deprecated = "depr")] Full,
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -37,10 +36,10 @@ fn test_derived_enum() {
|
|||
// Test FULL variant.
|
||||
assert_eq!(
|
||||
SomeEnum::Full.to_input_value(),
|
||||
InputValue::String("full".into())
|
||||
InputValue::String("FULL".into())
|
||||
);
|
||||
assert_eq!(
|
||||
FromInputValue::from_input_value(&InputValue::String("full".into())),
|
||||
FromInputValue::from_input_value(&InputValue::String("FULL".into())),
|
||||
Some(SomeEnum::Full)
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue