Format entire codebase with rustfmt

This commit is contained in:
Christoph Herzog 2018-01-13 12:25:55 +01:00
parent 406bdaa55c
commit d00e74bb4e
74 changed files with 2910 additions and 1786 deletions

View file

@ -402,9 +402,9 @@ impl InputValue {
(&Null, &Null) => true,
(&Int(i1), &Int(i2)) => i1 == i2,
(&Float(f1), &Float(f2)) => f1 == f2,
(&String(ref s1), &String(ref s2)) |
(&Enum(ref s1), &Enum(ref s2)) |
(&Variable(ref s1), &Variable(ref s2)) => s1 == s2,
(&String(ref s1), &String(ref s2))
| (&Enum(ref s1), &Enum(ref s2))
| (&Variable(ref s1), &Variable(ref s2)) => s1 == s2,
(&Boolean(b1), &Boolean(b2)) => b1 == b2,
(&List(ref l1), &List(ref l2)) => l1.iter()
.zip(l2.iter())

View file

@ -68,15 +68,21 @@ impl Eq for ExecutionError {}
impl PartialOrd for ExecutionError {
fn partial_cmp(&self, other: &ExecutionError) -> Option<Ordering> {
(&self.location, &self.path, &self.error.message)
.partial_cmp(&(&other.location, &other.path, &other.error.message))
(&self.location, &self.path, &self.error.message).partial_cmp(&(
&other.location,
&other.path,
&other.error.message,
))
}
}
impl Ord for ExecutionError {
fn cmp(&self, other: &ExecutionError) -> Ordering {
(&self.location, &self.path, &self.error.message)
.cmp(&(&other.location, &other.path, &other.error.message))
(&self.location, &self.path, &self.error.message).cmp(&(
&other.location,
&other.path,
&other.error.message,
))
}
}
@ -213,7 +219,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)>> {
impl<'a, T: GraphQLType, C> IntoResolvable<'a, Option<T>, C>
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))))
}
@ -329,8 +336,10 @@ impl<'a, CtxT> Executor<'a, CtxT> {
current_type: self.schema.make_type(
&self.current_type
.innermost_concrete()
.field_by_name(field_name).expect("Field not found on inner type")
.field_type),
.field_by_name(field_name)
.expect("Field not found on inner type")
.field_type,
),
schema: self.schema,
context: self.context,
errors: self.errors,
@ -478,8 +487,8 @@ where
return Err(GraphQLError::MultipleOperationsProvided);
}
let move_op = operation_name.is_none() ||
op.item.name.as_ref().map(|s| s.item.as_ref()) == operation_name;
let move_op = operation_name.is_none()
|| op.item.name.as_ref().map(|s| s.item.as_ref()) == operation_name;
if move_op {
operation = Some(op);
@ -525,7 +534,10 @@ where
let root_type = match op.item.operation_type {
OperationType::Query => root_node.schema.query_type(),
OperationType::Mutation => root_node.schema.mutation_type().expect("No mutation type found")
OperationType::Mutation => root_node
.schema
.mutation_type()
.expect("No mutation type found"),
};
let executor = Executor {

View file

@ -73,47 +73,50 @@ fn scalar_skip_true() {
});
}
#[test]
fn fragment_spread_include_true() {
run_query("{ a, ...Frag @include(if: true) } fragment Frag on TestType { b }",
|result| {
assert_eq!(result.get("a"), Some(&Value::string("a")));
assert_eq!(result.get("b"), Some(&Value::string("b")));
});
run_query(
"{ a, ...Frag @include(if: true) } fragment Frag on TestType { b }",
|result| {
assert_eq!(result.get("a"), Some(&Value::string("a")));
assert_eq!(result.get("b"), Some(&Value::string("b")));
},
);
}
#[test]
fn fragment_spread_include_false() {
run_query("{ a, ...Frag @include(if: false) } fragment Frag on TestType { b }",
|result| {
assert_eq!(result.get("a"), Some(&Value::string("a")));
assert_eq!(result.get("b"), None);
});
run_query(
"{ a, ...Frag @include(if: false) } fragment Frag on TestType { b }",
|result| {
assert_eq!(result.get("a"), Some(&Value::string("a")));
assert_eq!(result.get("b"), None);
},
);
}
#[test]
fn fragment_spread_skip_false() {
run_query("{ a, ...Frag @skip(if: false) } fragment Frag on TestType { b }",
|result| {
assert_eq!(result.get("a"), Some(&Value::string("a")));
assert_eq!(result.get("b"), Some(&Value::string("b")));
});
run_query(
"{ a, ...Frag @skip(if: false) } fragment Frag on TestType { b }",
|result| {
assert_eq!(result.get("a"), Some(&Value::string("a")));
assert_eq!(result.get("b"), Some(&Value::string("b")));
},
);
}
#[test]
fn fragment_spread_skip_true() {
run_query("{ a, ...Frag @skip(if: true) } fragment Frag on TestType { b }",
|result| {
assert_eq!(result.get("a"), Some(&Value::string("a")));
assert_eq!(result.get("b"), None);
});
run_query(
"{ a, ...Frag @skip(if: true) } fragment Frag on TestType { b }",
|result| {
assert_eq!(result.get("a"), Some(&Value::string("a")));
assert_eq!(result.get("b"), None);
},
);
}
#[test]
fn inline_fragment_include_true() {
run_query(
@ -152,9 +155,6 @@ fn inline_fragment_skip_true() {
});
}
#[test]
fn anonymous_inline_fragment_include_true() {
run_query("{ a, ... @include(if: true) { b } }", |result| {
@ -187,9 +187,6 @@ fn anonymous_inline_fragment_skip_true() {
});
}
#[test]
fn scalar_include_true_skip_true() {
run_query("{ a, b @include(if: true) @skip(if: true) }", |result| {

View file

@ -55,18 +55,14 @@ where
#[test]
fn accepts_enum_literal() {
run_query("{ toString(color: RED) }", |result| {
assert_eq!(
result.get("toString"),
Some(&Value::string("Color::Red")));
assert_eq!(result.get("toString"), Some(&Value::string("Color::Red")));
});
}
#[test]
fn serializes_as_output() {
run_query("{ aColor }", |result| {
assert_eq!(
result.get("aColor"),
Some(&Value::string("RED")));
assert_eq!(result.get("aColor"), Some(&Value::string("RED")));
});
}
@ -79,26 +75,26 @@ fn does_not_accept_string_literals() {
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
assert_eq!(error, ValidationError(vec![
RuleError::new(
r#"Invalid value for argument "color", expected type "Color!""#,
&[SourcePosition::new(18, 0, 18)],
),
]));
assert_eq!(
error,
ValidationError(vec![
RuleError::new(
r#"Invalid value for argument "color", expected type "Color!""#,
&[SourcePosition::new(18, 0, 18)],
),
])
);
}
#[test]
fn accepts_strings_in_variables() {
run_variable_query(
"query q($color: Color!) { toString(color: $color) }",
vec![
("color".to_owned(), InputValue::string("RED")),
].into_iter()
vec![("color".to_owned(), InputValue::string("RED"))]
.into_iter()
.collect(),
|result| {
assert_eq!(
result.get("toString"),
Some(&Value::string("Color::Red")));
assert_eq!(result.get("toString"), Some(&Value::string("Color::Red")));
},
);
}
@ -108,19 +104,21 @@ fn does_not_accept_incorrect_enum_name_in_variables() {
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
let query = r#"query q($color: Color!) { toString(color: $color) }"#;
let vars = vec![
("color".to_owned(), InputValue::string("BLURPLE")),
].into_iter()
let vars = vec![("color".to_owned(), InputValue::string("BLURPLE"))]
.into_iter()
.collect();
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
assert_eq!(error, ValidationError(vec![
RuleError::new(
r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#,
&[SourcePosition::new(8, 0, 8)],
),
]));
assert_eq!(
error,
ValidationError(vec![
RuleError::new(
r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#,
&[SourcePosition::new(8, 0, 8)],
),
])
);
}
#[test]
@ -128,17 +126,19 @@ fn does_not_accept_incorrect_type_in_variables() {
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
let query = r#"query q($color: Color!) { toString(color: $color) }"#;
let vars = vec![
("color".to_owned(), InputValue::int(123)),
].into_iter()
let vars = vec![("color".to_owned(), InputValue::int(123))]
.into_iter()
.collect();
let error = ::execute(query, None, &schema, &vars, &()).unwrap_err();
assert_eq!(error, ValidationError(vec![
assert_eq!(
error,
ValidationError(vec![
RuleError::new(
r#"Variable "$color" got invalid value. Expected "Color", found not a string or enum."#,
&[SourcePosition::new(8, 0, 8)],
),
]));
])
);
}

View file

@ -61,9 +61,8 @@ mod field_execution {
e
}";
let vars = vec![
("size".to_owned(), InputValue::int(100))
].into_iter()
let vars = vec![("size".to_owned(), InputValue::int(100))]
.into_iter()
.collect();
let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
@ -74,39 +73,60 @@ mod field_execution {
assert_eq!(
result,
Value::object(vec![
("a", Value::string("Apple")),
("b", Value::string("Banana")),
("x", Value::string("Cookie")),
("d", Value::string("Donut")),
("e", Value::string("Egg")),
("f", Value::string("Fish")),
("pic", Value::string("Pic of size: 100")),
("deep", Value::object(vec![
("a", Value::string("Already Been Done")),
("b", Value::string("Boring")),
("c", Value::list(vec![
Value::string("Contrived"),
Value::null(),
Value::string("Confusing"),
])),
("deeper", Value::list(vec![
Value::object(vec![
("a", Value::string("Apple")),
("b", Value::string("Banana")),
].into_iter().collect()),
Value::null(),
Value::object(vec![
("a", Value::string("Apple")),
("b", Value::string("Banana")),
].into_iter().collect()),
])),
].into_iter().collect())),
].into_iter().collect()));
Value::object(
vec![
("a", Value::string("Apple")),
("b", Value::string("Banana")),
("x", Value::string("Cookie")),
("d", Value::string("Donut")),
("e", Value::string("Egg")),
("f", Value::string("Fish")),
("pic", Value::string("Pic of size: 100")),
(
"deep",
Value::object(
vec![
("a", Value::string("Already Been Done")),
("b", Value::string("Boring")),
(
"c",
Value::list(vec![
Value::string("Contrived"),
Value::null(),
Value::string("Confusing"),
]),
),
(
"deeper",
Value::list(vec![
Value::object(
vec![
("a", Value::string("Apple")),
("b", Value::string("Banana")),
].into_iter()
.collect(),
),
Value::null(),
Value::object(
vec![
("a", Value::string("Apple")),
("b", Value::string("Banana")),
].into_iter()
.collect(),
),
]),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
)
);
}
}
mod merge_parallel_fragments {
use value::Value;
use schema::model::RootNode;
@ -145,19 +165,35 @@ mod merge_parallel_fragments {
assert_eq!(
result,
Value::object(vec![
("a", Value::string("Apple")),
("b", Value::string("Banana")),
("deep", Value::object(vec![
Value::object(
vec![
("a", Value::string("Apple")),
("b", Value::string("Banana")),
("deeper", Value::object(vec![
("b", Value::string("Banana")),
("c", Value::string("Cherry")),
].into_iter().collect())),
(
"deep",
Value::object(
vec![
("b", Value::string("Banana")),
(
"deeper",
Value::object(
vec![
("b", Value::string("Banana")),
("c", Value::string("Cherry")),
].into_iter()
.collect(),
),
),
("c", Value::string("Cherry")),
].into_iter()
.collect(),
),
),
("c", Value::string("Cherry")),
].into_iter().collect())),
("c", Value::string("Cherry")),
].into_iter().collect()));
].into_iter()
.collect()
)
);
}
}
@ -202,9 +238,12 @@ mod threads_context_correctly {
assert_eq!(
result,
Value::object(vec![
("a", Value::string("Context value")),
].into_iter().collect()));
Value::object(
vec![("a", Value::string("Context value"))]
.into_iter()
.collect()
)
);
}
}
@ -272,8 +311,18 @@ mod dynamic_context_switching {
let ctx = OuterContext {
items: vec![
(0, InnerContext { value: "First value".to_owned() }),
(1, InnerContext { value: "Second value".to_owned() }),
(
0,
InnerContext {
value: "First value".to_owned(),
},
),
(
1,
InnerContext {
value: "Second value".to_owned(),
},
),
].into_iter()
.collect(),
};
@ -286,12 +335,21 @@ mod dynamic_context_switching {
assert_eq!(
result,
Value::object(vec![
("first", Value::object(vec![
("value", Value::string("First value")),
].into_iter().collect())),
("missing", Value::null()),
].into_iter().collect()));
Value::object(
vec![
(
"first",
Value::object(
vec![("value", Value::string("First value"))]
.into_iter()
.collect(),
),
),
("missing", Value::null()),
].into_iter()
.collect()
)
);
}
#[test]
@ -307,8 +365,18 @@ mod dynamic_context_switching {
let ctx = OuterContext {
items: vec![
(0, InnerContext { value: "First value".to_owned() }),
(1, InnerContext { value: "Second value".to_owned() }),
(
0,
InnerContext {
value: "First value".to_owned(),
},
),
(
1,
InnerContext {
value: "Second value".to_owned(),
},
),
].into_iter()
.collect(),
};
@ -321,11 +389,20 @@ mod dynamic_context_switching {
assert_eq!(
result,
Value::object(vec![
("first", Value::object(vec![
("value", Value::string("First value")),
].into_iter().collect())),
].into_iter().collect()));
Value::object(
vec![
(
"first",
Value::object(
vec![("value", Value::string("First value"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
)
);
}
#[test]
@ -341,21 +418,34 @@ mod dynamic_context_switching {
let ctx = OuterContext {
items: vec![
(0, InnerContext { value: "First value".to_owned() }),
(1, InnerContext { value: "Second value".to_owned() }),
(
0,
InnerContext {
value: "First value".to_owned(),
},
),
(
1,
InnerContext {
value: "Second value".to_owned(),
},
),
].into_iter()
.collect(),
};
let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx).expect("Execution failed");
assert_eq!(errs, vec![
ExecutionError::new(
SourcePosition::new(25, 2, 12),
&["missing"],
FieldError::new("Could not find key 2", Value::null()),
),
]);
assert_eq!(
errs,
vec![
ExecutionError::new(
SourcePosition::new(25, 2, 12),
&["missing"],
FieldError::new("Could not find key 2", Value::null()),
),
]
);
println!("Result: {:?}", result);
@ -377,33 +467,55 @@ mod dynamic_context_switching {
let ctx = OuterContext {
items: vec![
(0, InnerContext { value: "First value".to_owned() }),
(1, InnerContext { value: "Second value".to_owned() }),
(
0,
InnerContext {
value: "First value".to_owned(),
},
),
(
1,
InnerContext {
value: "Second value".to_owned(),
},
),
].into_iter()
.collect(),
};
let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx).expect("Execution failed");
assert_eq!(errs, [
ExecutionError::new(
SourcePosition::new(123, 4, 12),
&["tooLarge"],
FieldError::new("Key too large: 200", Value::null()),
),
]);
assert_eq!(
errs,
[
ExecutionError::new(
SourcePosition::new(123, 4, 12),
&["tooLarge"],
FieldError::new("Key too large: 200", Value::null()),
),
]
);
println!("Result: {:?}", result);
assert_eq!(
result,
Value::object(vec![
("first", Value::object(vec![
("value", Value::string("First value")),
].into_iter().collect())),
("missing", Value::null()),
("tooLarge", Value::null()),
].into_iter().collect()));
Value::object(
vec![
(
"first",
Value::object(
vec![("value", Value::string("First value"))]
.into_iter()
.collect(),
),
),
("missing", Value::null()),
("tooLarge", Value::null()),
].into_iter()
.collect()
)
);
}
#[test]
@ -415,8 +527,18 @@ mod dynamic_context_switching {
let ctx = OuterContext {
items: vec![
(0, InnerContext { value: "First value".to_owned() }),
(1, InnerContext { value: "Second value".to_owned() }),
(
0,
InnerContext {
value: "First value".to_owned(),
},
),
(
1,
InnerContext {
value: "Second value".to_owned(),
},
),
].into_iter()
.collect(),
};
@ -429,11 +551,20 @@ mod dynamic_context_switching {
assert_eq!(
result,
Value::object(vec![
("first", Value::object(vec![
("value", Value::string("First value")),
].into_iter().collect())),
].into_iter().collect()));
Value::object(
vec![
(
"first",
Value::object(
vec![("value", Value::string("First value"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
)
);
}
}
@ -473,7 +604,8 @@ mod propagates_errors_to_nullable_fields {
assert_eq!(
result,
graphql_value!({ "inner": { "nullableErrorField": None } }));
graphql_value!({ "inner": { "nullableErrorField": None } })
);
assert_eq!(
errs,
@ -483,7 +615,8 @@ mod propagates_errors_to_nullable_fields {
&["inner", "nullableErrorField"],
FieldError::new("Error for nullableErrorField", Value::null()),
),
]);
]
);
}
#[test]
@ -497,9 +630,7 @@ mod propagates_errors_to_nullable_fields {
println!("Result: {:?}", result);
assert_eq!(
result,
graphql_value!(None));
assert_eq!(result, graphql_value!(None));
assert_eq!(
errs,
@ -509,7 +640,8 @@ mod propagates_errors_to_nullable_fields {
&["inner", "nonNullableErrorField"],
FieldError::new("Error for nonNullableErrorField", Value::null()),
),
]);
]
);
}
#[test]
@ -525,7 +657,8 @@ mod propagates_errors_to_nullable_fields {
assert_eq!(
result,
graphql_value!({ "inner": { "nullableField": None } }));
graphql_value!({ "inner": { "nullableField": None } })
);
assert_eq!(
errs,
@ -535,7 +668,8 @@ mod propagates_errors_to_nullable_fields {
&["inner", "nullableField", "nonNullableErrorField"],
FieldError::new("Error for nonNullableErrorField", Value::null()),
),
]);
]
);
}
#[test]
@ -549,9 +683,7 @@ mod propagates_errors_to_nullable_fields {
println!("Result: {:?}", result);
assert_eq!(
result,
graphql_value!(None));
assert_eq!(result, graphql_value!(None));
assert_eq!(
errs,
@ -561,7 +693,8 @@ mod propagates_errors_to_nullable_fields {
&["inner", "nonNullableField", "nonNullableErrorField"],
FieldError::new("Error for nonNullableErrorField", Value::null()),
),
]);
]
);
}
#[test]
@ -577,7 +710,8 @@ mod propagates_errors_to_nullable_fields {
assert_eq!(
result,
graphql_value!({ "inner": { "nonNullableField": { "nullableErrorField": None } } }));
graphql_value!({ "inner": { "nonNullableField": { "nullableErrorField": None } } })
);
assert_eq!(
errs,
@ -587,7 +721,8 @@ mod propagates_errors_to_nullable_fields {
&["inner", "nonNullableField", "nullableErrorField"],
FieldError::new("Error for nullableErrorField", Value::null()),
),
]);
]
);
}
#[test]
@ -601,9 +736,7 @@ mod propagates_errors_to_nullable_fields {
println!("Result: {:?}", result);
assert_eq!(
result,
graphql_value!(None));
assert_eq!(result, graphql_value!(None));
assert_eq!(
errs,
@ -613,7 +746,8 @@ mod propagates_errors_to_nullable_fields {
&["inners", "nonNullableErrorField"],
FieldError::new("Error for nonNullableErrorField", Value::null()),
),
]);
]
);
}
#[test]
@ -629,7 +763,8 @@ mod propagates_errors_to_nullable_fields {
assert_eq!(
result,
graphql_value!({ "nullableInners": [None, None, None, None, None] }));
graphql_value!({ "nullableInners": [None, None, None, None, None] })
);
assert_eq!(
errs,
@ -659,7 +794,8 @@ mod propagates_errors_to_nullable_fields {
&["nullableInners", "nonNullableErrorField"],
FieldError::new("Error for nonNullableErrorField", Value::null()),
),
]);
]
);
}
}
@ -688,9 +824,8 @@ mod named_operations {
assert_eq!(
result,
Value::object(vec![
("a", Value::string("b")),
].into_iter().collect()));
Value::object(vec![("a", Value::string("b"))].into_iter().collect())
);
}
#[test]
@ -706,9 +841,8 @@ mod named_operations {
assert_eq!(
result,
Value::object(vec![
("a", Value::string("b")),
].into_iter().collect()));
Value::object(vec![("a", Value::string("b"))].into_iter().collect())
);
}
#[test]
@ -725,9 +859,8 @@ mod named_operations {
assert_eq!(
result,
Value::object(vec![
("second", Value::string("b")),
].into_iter().collect()));
Value::object(vec![("second", Value::string("b"))].into_iter().collect())
);
}
#[test]

View file

@ -80,8 +80,14 @@ mod interface {
let schema = RootNode::new(
Schema {
pets: vec![
Box::new(Dog { name: "Odie".to_owned(), woofs: true }),
Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
Box::new(Dog {
name: "Odie".to_owned(),
woofs: true,
}),
Box::new(Cat {
name: "Garfield".to_owned(),
meows: false,
}),
],
},
EmptyMutation::<()>::new(),
@ -109,24 +115,34 @@ 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().collect()));
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()
.collect()
)
);
}
}
mod union {
use value::Value;
use schema::model::RootNode;
@ -195,8 +211,14 @@ mod union {
let schema = RootNode::new(
Schema {
pets: vec![
Box::new(Dog { name: "Odie".to_owned(), woofs: true }),
Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
Box::new(Dog {
name: "Odie".to_owned(),
woofs: true,
}),
Box::new(Cat {
name: "Garfield".to_owned(),
meows: false,
}),
],
},
EmptyMutation::<()>::new(),
@ -226,19 +248,32 @@ 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().collect()));
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()
.collect()
)
);
}
}

View file

@ -48,19 +48,15 @@ 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;
@ -127,19 +123,29 @@ fn default_name_introspection() {
assert_eq!(values.len(), 2);
assert!(values.contains(&Value::object(vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
assert!(values.contains(&Value::object(vec![
("name", Value::string("BAR")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("BAR")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -166,19 +172,29 @@ fn named_introspection() {
assert_eq!(values.len(), 2);
assert!(values.contains(&Value::object(vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
assert!(values.contains(&Value::object(vec![
("name", Value::string("BAR")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("BAR")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -200,24 +216,37 @@ fn no_trailing_comma_introspection() {
"#;
run_type_info_query(doc, |(type_info, values)| {
assert_eq!(type_info.get("name"), Some(&Value::string("NoTrailingComma")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("NoTrailingComma"))
);
assert_eq!(type_info.get("description"), Some(&Value::null()));
assert_eq!(values.len(), 2);
assert!(values.contains(&Value::object(vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
assert!(values.contains(&Value::object(vec![
("name", Value::string("BAR")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("BAR")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -239,24 +268,40 @@ fn enum_description_introspection() {
"#;
run_type_info_query(doc, |(type_info, values)| {
assert_eq!(type_info.get("name"), Some(&Value::string("EnumDescription")));
assert_eq!(type_info.get("description"), Some(&Value::string("A description of the enum itself")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("EnumDescription"))
);
assert_eq!(
type_info.get("description"),
Some(&Value::string("A description of the enum itself"))
);
assert_eq!(values.len(), 2);
assert!(values.contains(&Value::object(vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
assert!(values.contains(&Value::object(vec![
("name", Value::string("BAR")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("BAR")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -278,24 +323,37 @@ fn enum_value_description_introspection() {
"#;
run_type_info_query(doc, |(type_info, values)| {
assert_eq!(type_info.get("name"), Some(&Value::string("EnumValueDescription")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("EnumValueDescription"))
);
assert_eq!(type_info.get("description"), Some(&Value::null()));
assert_eq!(values.len(), 2);
assert!(values.contains(&Value::object(vec![
("name", Value::string("FOO")),
("description", Value::string("The FOO value")),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("FOO")),
("description", Value::string("The FOO value")),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
assert!(values.contains(&Value::object(vec![
("name", Value::string("BAR")),
("description", Value::string("The BAR value")),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("BAR")),
("description", Value::string("The BAR value")),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -317,24 +375,43 @@ fn enum_deprecation_introspection() {
"#;
run_type_info_query(doc, |(type_info, values)| {
assert_eq!(type_info.get("name"), Some(&Value::string("EnumDeprecation")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("EnumDeprecation"))
);
assert_eq!(type_info.get("description"), Some(&Value::null()));
assert_eq!(values.len(), 2);
assert!(values.contains(&Value::object(vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(true)),
("deprecationReason", Value::string("Please don't use FOO any more")),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("FOO")),
("description", Value::null()),
("isDeprecated", Value::boolean(true)),
(
"deprecationReason",
Value::string("Please don't use FOO any more"),
),
].into_iter()
.collect()
))
);
assert!(values.contains(&Value::object(vec![
("name", Value::string("BAR")),
("description", Value::string("The BAR value")),
("isDeprecated", Value::boolean(true)),
("deprecationReason", Value::string("Please don't use BAR any more")),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("BAR")),
("description", Value::string("The BAR value")),
("isDeprecated", Value::boolean(true)),
(
"deprecationReason",
Value::string("Please don't use BAR any more"),
),
].into_iter()
.collect()
))
);
});
}
@ -356,7 +433,10 @@ fn enum_deprecation_no_values_introspection() {
"#;
run_type_info_query(doc, |(type_info, values)| {
assert_eq!(type_info.get("name"), Some(&Value::string("EnumDeprecation")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("EnumDeprecation"))
);
assert_eq!(type_info.get("description"), Some(&Value::null()));
assert_eq!(values.len(), 0);

View file

@ -19,7 +19,7 @@ struct DefaultName {
#[graphql(_internal)]
struct NoTrailingComma {
field_one: String,
field_two: String
field_two: String,
}
#[derive(GraphQLInputObject, Debug)]
@ -54,8 +54,7 @@ pub struct PublicWithDescription {
#[derive(GraphQLInputObject, Debug)]
#[graphql(name = "APublicNamedInputObjectWithDescription",
description = "Description for the input object",
_internal)]
description = "Description for the input object", _internal)]
pub struct NamedPublicWithDescription {
field_one: String,
}
@ -69,19 +68,15 @@ 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| {
@ -159,27 +154,59 @@ fn default_name_introspection() {
assert_eq!(fields.len(), 2);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldTwo")),
("description", Value::null()),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldTwo")),
("description", Value::null()),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -187,9 +214,9 @@ fn default_name_introspection() {
fn default_name_input_value() {
let iv = InputValue::object(
vec![
("fieldOne", InputValue::string("number one")),
("fieldTwo", InputValue::string("number two")),
].into_iter()
("fieldOne", InputValue::string("number one")),
("fieldTwo", InputValue::string("number two")),
].into_iter()
.collect(),
);
@ -225,32 +252,67 @@ fn no_trailing_comma_introspection() {
"#;
run_type_info_query(doc, |type_info, fields| {
assert_eq!(type_info.get("name"), Some(&Value::string("NoTrailingComma")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("NoTrailingComma"))
);
assert_eq!(type_info.get("description"), Some(&Value::null()));
assert_eq!(fields.len(), 2);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldTwo")),
("description", Value::null()),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldTwo")),
("description", Value::null()),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -281,23 +343,44 @@ fn derive_introspection() {
assert_eq!(fields.len(), 1);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
});
}
#[test]
fn derive_derived() {
assert_eq!(
format!("{:?}", Derive { field_one: "test".to_owned() }),
format!(
"{:?}",
Derive {
field_one: "test".to_owned(),
}
),
"Derive { field_one: \"test\" }"
);
}
@ -324,21 +407,40 @@ fn named_introspection() {
"#;
run_type_info_query(doc, |type_info, fields| {
assert_eq!(type_info.get("name"), Some(&Value::string("ANamedInputObject")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("ANamedInputObject"))
);
assert_eq!(type_info.get("description"), Some(&Value::null()));
assert_eq!(fields.len(), 1);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -365,20 +467,39 @@ fn description_introspection() {
run_type_info_query(doc, |type_info, fields| {
assert_eq!(type_info.get("name"), Some(&Value::string("Description")));
assert_eq!(type_info.get("description"), Some(&Value::string("Description for the input object")));
assert_eq!(
type_info.get("description"),
Some(&Value::string("Description for the input object"))
);
assert_eq!(fields.len(), 1);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldOne")),
("description", Value::null()),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -404,32 +525,67 @@ fn field_description_introspection() {
"#;
run_type_info_query(doc, |type_info, fields| {
assert_eq!(type_info.get("name"), Some(&Value::string("FieldDescription")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("FieldDescription"))
);
assert_eq!(type_info.get("description"), Some(&Value::null()));
assert_eq!(fields.len(), 2);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldOne")),
("description", Value::string("The first field")),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldOne")),
("description", Value::string("The first field")),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldTwo")),
("description", Value::string("The second field")),
("type", Value::object(vec![
("ofType", Value::object(vec![
("name", Value::string("String")),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldTwo")),
("description", Value::string("The second field")),
(
"type",
Value::object(
vec![
(
"ofType",
Value::object(
vec![("name", Value::string("String"))]
.into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect()
))
);
});
}
@ -451,24 +607,39 @@ fn field_with_defaults_introspection() {
"#;
run_type_info_query(doc, |type_info, fields| {
assert_eq!(type_info.get("name"), Some(&Value::string("FieldWithDefaults")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("FieldWithDefaults"))
);
assert_eq!(fields.len(), 2);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldOne")),
("type", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
("defaultValue", Value::string("123")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldOne")),
(
"type",
Value::object(vec![("name", Value::string("Int"))].into_iter().collect()),
),
("defaultValue", Value::string("123")),
].into_iter()
.collect()
))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("fieldTwo")),
("type", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
("defaultValue", Value::string("456")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("fieldTwo")),
(
"type",
Value::object(vec![("name", Value::string("Int"))].into_iter().collect()),
),
("defaultValue", Value::string("456")),
].into_iter()
.collect()
))
);
});
}

View file

@ -80,11 +80,17 @@ fn test_execution() {
println!("Result: {:?}", result);
assert_eq!(result, Value::object(vec![
("sampleEnum", Value::string("ONE")),
("first", Value::int(123)),
("second", Value::int(30)),
].into_iter().collect()));
assert_eq!(
result,
Value::object(
vec![
("sampleEnum", Value::string("ONE")),
("first", Value::int(123)),
("second", Value::int(30)),
].into_iter()
.collect()
)
);
}
#[test]
@ -141,19 +147,29 @@ fn enum_introspection() {
assert_eq!(values.len(), 2);
assert!(values.contains(&Value::object(vec![
("name", Value::string("ONE")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("ONE")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
assert!(values.contains(&Value::object(vec![
("name", Value::string("TWO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
values.contains(&Value::object(
vec![
("name", Value::string("TWO")),
("description", Value::null()),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
}
#[test]
@ -208,9 +224,15 @@ fn interface_introspection() {
.as_object_value()
.expect("__type field not an object value");
assert_eq!(type_info.get("name"), Some(&Value::string("SampleInterface")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("SampleInterface"))
);
assert_eq!(type_info.get("kind"), Some(&Value::string("INTERFACE")));
assert_eq!(type_info.get("description"), Some(&Value::string("A sample interface")));
assert_eq!(
type_info.get("description"),
Some(&Value::string("A sample interface"))
);
assert_eq!(type_info.get("interfaces"), Some(&Value::null()));
assert_eq!(type_info.get("enumValues"), Some(&Value::null()));
assert_eq!(type_info.get("inputFields"), Some(&Value::null()));
@ -224,9 +246,9 @@ fn interface_introspection() {
assert_eq!(possible_types.len(), 1);
assert!(possible_types.contains(&Value::object(vec![
("name", Value::string("Root")),
].into_iter().collect())));
assert!(possible_types.contains(&Value::object(
vec![("name", Value::string("Root"))].into_iter().collect()
)));
let fields = type_info
.get("fields")
@ -236,21 +258,41 @@ fn interface_introspection() {
assert_eq!(fields.len(), 1);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("sampleEnum")),
("description", Value::string("A sample field in the interface")),
("args", Value::list(vec![])),
("type", Value::object(vec![
("name", Value::null()),
("kind", Value::string("NON_NULL")),
("ofType", Value::object(vec![
("name", Value::string("SampleEnum")),
("kind", Value::string("ENUM")),
].into_iter().collect())),
].into_iter().collect())),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("sampleEnum")),
(
"description",
Value::string("A sample field in the interface"),
),
("args", Value::list(vec![])),
(
"type",
Value::object(
vec![
("name", Value::null()),
("kind", Value::string("NON_NULL")),
(
"ofType",
Value::object(
vec![
("name", Value::string("SampleEnum")),
("kind", Value::string("ENUM")),
].into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
}
#[test]
@ -318,14 +360,20 @@ fn object_introspection() {
assert_eq!(type_info.get("name"), Some(&Value::string("Root")));
assert_eq!(type_info.get("kind"), Some(&Value::string("OBJECT")));
assert_eq!(type_info.get("description"), Some(&Value::string("The root query object in the schema")));
assert_eq!(
type_info.get("description"),
Some(&Value::string("The root query object in the schema"))
);
assert_eq!(
type_info.get("interfaces"),
Some(&Value::list(vec![
Value::object(vec![
("name", Value::string("SampleInterface")),
].into_iter().collect()),
])));
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()));
assert_eq!(type_info.get("ofType"), Some(&Value::null()));
@ -341,62 +389,126 @@ fn object_introspection() {
println!("Fields: {:#?}", fields);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("sampleEnum")),
("description", Value::null()),
("args", Value::list(vec![])),
("type", Value::object(vec![
("name", Value::null()),
("kind", Value::string("NON_NULL")),
("ofType", Value::object(vec![
("name", Value::string("SampleEnum")),
("kind", Value::string("ENUM")),
].into_iter().collect())),
].into_iter().collect())),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("sampleEnum")),
("description", Value::null()),
("args", Value::list(vec![])),
(
"type",
Value::object(
vec![
("name", Value::null()),
("kind", Value::string("NON_NULL")),
(
"ofType",
Value::object(
vec![
("name", Value::string("SampleEnum")),
("kind", Value::string("ENUM")),
].into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("sampleScalar")),
("description", Value::string("A sample scalar field on the object")),
("args", Value::list(vec![
Value::object(vec![
("name", Value::string("first")),
("description", Value::string("The first number")),
("type", Value::object(vec![
("name", Value::null()),
("kind", Value::string("NON_NULL")),
("ofType", Value::object(vec![
("name", Value::string("Int")),
("kind", Value::string("SCALAR")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())),
("defaultValue", Value::null()),
].into_iter().collect()),
Value::object(vec![
("name", Value::string("second")),
("description", Value::string("The second number")),
("type", Value::object(vec![
("name", Value::string("Int")),
("kind", Value::string("SCALAR")),
("ofType", Value::null()),
].into_iter().collect())),
("defaultValue", Value::string("123")),
].into_iter().collect()),
])),
("type", Value::object(vec![
("name", Value::null()),
("kind", Value::string("NON_NULL")),
("ofType", Value::object(vec![
("name", Value::string("SampleScalar")),
("kind", Value::string("SCALAR")),
].into_iter().collect())),
].into_iter().collect())),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![
("name", Value::string("sampleScalar")),
(
"description",
Value::string("A sample scalar field on the object"),
),
(
"args",
Value::list(vec![
Value::object(
vec![
("name", Value::string("first")),
("description", Value::string("The first number")),
(
"type",
Value::object(
vec![
("name", Value::null()),
("kind", Value::string("NON_NULL")),
(
"ofType",
Value::object(
vec![
("name", Value::string("Int")),
("kind", Value::string("SCALAR")),
("ofType", Value::null()),
].into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("defaultValue", Value::null()),
].into_iter()
.collect(),
),
Value::object(
vec![
("name", Value::string("second")),
("description", Value::string("The second number")),
(
"type",
Value::object(
vec![
("name", Value::string("Int")),
("kind", Value::string("SCALAR")),
("ofType", Value::null()),
].into_iter()
.collect(),
),
),
("defaultValue", Value::string("123")),
].into_iter()
.collect(),
),
]),
),
(
"type",
Value::object(
vec![
("name", Value::null()),
("kind", Value::string("NON_NULL")),
(
"ofType",
Value::object(
vec![
("name", Value::string("SampleScalar")),
("kind", Value::string("SCALAR")),
].into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
("isDeprecated", Value::boolean(false)),
("deprecationReason", Value::null()),
].into_iter()
.collect()
))
);
}
#[test]
@ -431,15 +543,21 @@ fn scalar_introspection() {
.get("__type")
.expect("__type field missing");
assert_eq!(type_info, &Value::object(vec![
("name", Value::string("SampleScalar")),
("kind", Value::string("SCALAR")),
("description", Value::null()),
("fields", Value::null()),
("interfaces", Value::null()),
("possibleTypes", Value::null()),
("enumValues", Value::null()),
("inputFields", Value::null()),
("ofType", Value::null()),
].into_iter().collect()));
assert_eq!(
type_info,
&Value::object(
vec![
("name", Value::string("SampleScalar")),
("kind", Value::string("SCALAR")),
("description", Value::null()),
("fields", Value::null()),
("interfaces", Value::null()),
("possibleTypes", Value::null()),
("enumValues", Value::null()),
("inputFields", Value::null()),
("ofType", Value::null()),
].into_iter()
.collect()
)
);
}

File diff suppressed because it is too large Load diff

View file

@ -62,5 +62,4 @@ pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
graphql_url = graphql_endpoint_url,
stylesheet_source = stylesheet_source,
fetcher_source = fetcher_source)
}

View file

@ -19,8 +19,7 @@ use executor::ExecutionError;
#[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>,
}

View file

@ -15,7 +15,7 @@
*/
use chrono::prelude::*;
use ::Value;
use Value;
#[doc(hidden)]
pub static RFC3339_FORMAT: &'static str = "%Y-%m-%dT%H:%M:%S%.f%:z";
@ -113,7 +113,9 @@ mod test {
let input = ::InputValue::String(raw.to_string());
let parsed: DateTime<Utc> = ::FromInputValue::from_input_value(&input).unwrap();
let expected = DateTime::parse_from_rfc3339(raw).unwrap().with_timezone(&Utc);
let expected = DateTime::parse_from_rfc3339(raw)
.unwrap()
.with_timezone(&Utc);
assert_eq!(parsed, expected);
}

View file

@ -47,9 +47,8 @@ impl<'a> ser::Serialize for GraphQLError<'a> {
GraphQLError::NoOperationProvided => {
serializer.serialize_str("Must provide an operation")
}
GraphQLError::MultipleOperationsProvided => serializer.serialize_str(
"Must provide operation name if query contains multiple operations",
),
GraphQLError::MultipleOperationsProvided => serializer
.serialize_str("Must provide operation name if query contains multiple operations"),
GraphQLError::UnknownOperationName => serializer.serialize_str("Unknown operation"),
}
}

View file

@ -1,6 +1,6 @@
use url::Url;
use ::Value;
use Value;
graphql_scalar!(Url {
description: "Url"

View file

@ -1,6 +1,6 @@
use uuid::Uuid;
use ::Value;
use Value;
graphql_scalar!(Uuid {
description: "Uuid"
@ -29,4 +29,4 @@ mod test {
assert_eq!(parsed, id);
}
}
}

View file

@ -212,5 +212,3 @@ impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
GraphQLError::ParseError(f)
}
}

View file

@ -5,7 +5,12 @@ macro_rules! __graphql__build_field_matches {
(
$resolveargs:tt,
( $( $acc:tt )* ),
field deprecated $_reason:tt $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
field deprecated $_reason:tt
$name:ident
$args:tt -> $t:ty
as $desc:tt
$body:block
$( $rest:tt )*
) => {
__graphql__build_field_matches!(
$resolveargs,
@ -28,7 +33,12 @@ macro_rules! __graphql__build_field_matches {
// field <name>(...) -> <type> as <description> { ... }
(
$resolveargs:tt,
( $( $acc:tt )* ), field $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
( $( $acc:tt )* ),
field $name:ident
$args:tt -> $t:ty
as $desc:tt
$body:block
$( $rest:tt )*
) => {
__graphql__build_field_matches!(
$resolveargs,
@ -55,7 +65,10 @@ macro_rules! __graphql__build_field_matches {
__graphql__build_field_matches!($resolveargs, $acc, $( $rest )*);
};
( $resolveargs:tt, $acc:tt, instance_resolvers : | $execvar:pat | $resolvers:tt $( $rest:tt )*) => {
( $resolveargs:tt,
$acc:tt,
instance_resolvers : | $execvar:pat | $resolvers:tt $( $rest:tt )*
) => {
__graphql__build_field_matches!($resolveargs, $acc, $( $rest )*);
};
@ -79,7 +92,8 @@ macro_rules! __graphql__build_field_matches {
return ($crate::IntoResolvable::into(result, $executorvar.context())).and_then(
|res| match res {
Some((ctx, r)) => $executorvar.replaced_context(ctx).resolve_with_ctx(&(), &r),
Some((ctx, r)) =>
$executorvar.replaced_context(ctx).resolve_with_ctx(&(), &r),
None => Ok($crate::Value::null()),
})
}

View file

@ -94,7 +94,11 @@ macro_rules! graphql_interface {
(
@ gather_meta,
($reg:expr, $acc:expr, $info:expr, $descr:expr),
field deprecated $reason:tt $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
field deprecated $reason:tt
$name:ident
$args:tt -> $t:ty as $desc:tt
$body:block
$( $rest:tt )*
) => {
$acc.push(__graphql__args!(
@apply_args,
@ -177,7 +181,8 @@ macro_rules! graphql_interface {
(
@ gather_meta,
($reg:expr, $acc:expr, $info:expr, $descr:expr),
instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
instance_resolvers : | $ctxtvar:pat
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
) => {
$(
let _ = $reg.get_type::<$srctype>(&());
@ -190,7 +195,8 @@ macro_rules! graphql_interface {
(
@ concrete_type_name,
($outname:tt, $ctxtarg:ident, $ctxttype:ty),
instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
instance_resolvers : | $ctxtvar:pat
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
) => {
let $ctxtvar = &$ctxtarg;
@ -207,7 +213,8 @@ macro_rules! graphql_interface {
(
@ resolve_into_type,
($outname:tt, $typenamearg:ident, $execarg:ident, $ctxttype:ty),
instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
instance_resolvers : | $ctxtvar:pat
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
) => {
let $ctxtvar = &$execarg.context();
@ -241,10 +248,15 @@ macro_rules! graphql_interface {
#[allow(unused_assignments)]
#[allow(unused_mut)]
fn meta<'r>(info: &(), registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
fn meta<'r>(
info: &(),
registry: &mut $crate::Registry<'r>
) -> $crate::meta::MetaType<'r> {
let mut fields = Vec::new();
let mut description = None;
graphql_interface!(@ gather_meta, (registry, fields, info, description), $($items)*);
graphql_interface!(
@ gather_meta, (registry, fields, info, description), $($items)*
);
let mut mt = registry.build_interface_type::<$name>(&(), &fields);
if let Some(description) = description {
@ -256,7 +268,13 @@ macro_rules! graphql_interface {
#[allow(unused_variables)]
#[allow(unused_mut)]
fn resolve_field(&$mainself, info: &(), field: &str, args: &$crate::Arguments, mut executor: &$crate::Executor<Self::Context>) -> $crate::ExecutionResult {
fn resolve_field(
&$mainself,
info: &(),
field: &str,
args: &$crate::Arguments,
mut executor: &$crate::Executor<Self::Context>
) -> $crate::ExecutionResult {
__graphql__build_field_matches!(
($outname, $mainself, field, args, executor),
(),

View file

@ -246,7 +246,13 @@ macro_rules! graphql_object {
(
@gather_object_meta,
$reg:expr, $acc:expr, $info:expr, $descr:expr, $ifaces:expr,
field deprecated $reason:tt $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
field deprecated
$reason:tt
$name:ident
$args:tt -> $t:ty
as $desc:tt
$body:block
$( $rest:tt )*
) => {
$acc.push(__graphql__args!(
@apply_args,
@ -376,7 +382,10 @@ macro_rules! graphql_object {
#[allow(unused_assignments)]
#[allow(unused_mut)]
fn meta<'r>(info: &(), registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
fn meta<'r>(
info: &(),
registry: &mut $crate::Registry<'r>
) -> $crate::meta::MetaType<'r> {
let mut fields = Vec::new();
let mut description = None;
let mut interfaces: Option<Vec<$crate::Type>> = None;

View file

@ -71,7 +71,10 @@ macro_rules! graphql_scalar {
Some(graphql_scalar!( @as_expr, $outname ))
}
fn meta<'r>(info: &(), registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
fn meta<'r>(
info: &(),
registry: &mut $crate::Registry<'r>
) -> $crate::meta::MetaType<'r> {
graphql_scalar!(
@maybe_apply, $descr, description,
registry.build_scalar_type::<Self>(info))

View file

@ -170,17 +170,31 @@ fn introspect_field_exec_arg_and_more() {
run_args_info_query("execArgAndMore", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -189,17 +203,31 @@ fn introspect_field_single_arg() {
run_args_info_query("singleArg", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -208,29 +236,57 @@ fn introspect_field_multi_args() {
run_args_info_query("multiArgs", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -239,29 +295,57 @@ fn introspect_field_multi_args_trailing_comma() {
run_args_info_query("multiArgsTrailingComma", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -270,17 +354,31 @@ fn introspect_field_single_arg_descr() {
run_args_info_query("singleArgDescr", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::string("The arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg")),
("description", Value::string("The arg")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -289,29 +387,57 @@ fn introspect_field_multi_args_descr() {
run_args_info_query("multiArgsDescr", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -320,29 +446,57 @@ fn introspect_field_multi_args_descr_trailing_comma() {
run_args_info_query("multiArgsDescrTrailingComma", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::null()),
(
"type",
Value::object(
vec![
("name", Value::null()),
(
"ofType",
Value::object(
vec![("name", Value::string("Int"))].into_iter().collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -351,15 +505,24 @@ fn introspect_field_arg_with_default() {
run_args_info_query("argWithDefault", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::string("123")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -368,25 +531,43 @@ fn introspect_field_multi_args_with_default() {
run_args_info_query("multiArgsWithDefault", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::string("123")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::string("456")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::string("456")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -395,25 +576,43 @@ fn introspect_field_multi_args_with_default_trailing_comma() {
run_args_info_query("multiArgsWithDefaultTrailingComma", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::string("123")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::string("456")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::string("456")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -422,15 +621,24 @@ fn introspect_field_arg_with_default_descr() {
run_args_info_query("argWithDefaultDescr", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::string("The arg")),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg")),
("description", Value::string("The arg")),
("defaultValue", Value::string("123")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -439,25 +647,43 @@ fn introspect_field_multi_args_with_default_descr() {
run_args_info_query("multiArgsWithDefaultDescr", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::string("123")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::string("456")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::string("456")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -466,25 +692,43 @@ fn introspect_field_multi_args_with_default_trailing_comma_descr() {
run_args_info_query("multiArgsWithDefaultTrailingCommaDescr", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::string("123")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::string("456")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::string("456")),
(
"type",
Value::object(
vec![("name", Value::string("Int")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}
@ -493,24 +737,45 @@ fn introspect_field_args_with_complex_default() {
run_args_info_query("argsWithComplexDefault", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("A string default argument")),
("defaultValue", Value::string(r#""test""#)),
("type", Value::object(vec![
("name", Value::string("String")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg1")),
("description", Value::string("A string default argument")),
("defaultValue", Value::string(r#""test""#)),
(
"type",
Value::object(
vec![("name", Value::string("String")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("An input object default argument")),
("defaultValue", Value::string(r#"{x: 1}"#)),
("type", Value::object(vec![
("name", Value::string("Point")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(
args.contains(&Value::object(
vec![
("name", Value::string("arg2")),
(
"description",
Value::string("An input object default argument"),
),
("defaultValue", Value::string(r#"{x: 1}"#)),
(
"type",
Value::object(
vec![("name", Value::string("Point")), ("ofType", Value::null())]
.into_iter()
.collect(),
),
),
].into_iter()
.collect()
))
);
});
}

View file

@ -74,9 +74,8 @@ where
}
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let vars = vec![
("typeName".to_owned(), InputValue::string(type_name)),
].into_iter()
let vars = vec![("typeName".to_owned(), InputValue::string(type_name))]
.into_iter()
.collect();
let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
@ -143,7 +142,10 @@ fn introspect_interface_field_simple() {
fn introspect_object_field_description() {
run_field_info_query("Root", "description", |field| {
assert_eq!(field.get("name"), Some(&Value::string("description")));
assert_eq!(field.get("description"), Some(&Value::string("Field description")));
assert_eq!(
field.get("description"),
Some(&Value::string("Field description"))
);
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(false)));
assert_eq!(field.get("deprecationReason"), Some(&Value::null()));
});
@ -153,7 +155,10 @@ fn introspect_object_field_description() {
fn introspect_interface_field_description() {
run_field_info_query("Interface", "description", |field| {
assert_eq!(field.get("name"), Some(&Value::string("description")));
assert_eq!(field.get("description"), Some(&Value::string("Field description")));
assert_eq!(
field.get("description"),
Some(&Value::string("Field description"))
);
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(false)));
assert_eq!(field.get("deprecationReason"), Some(&Value::null()));
});
@ -165,7 +170,10 @@ fn introspect_object_field_deprecated() {
assert_eq!(field.get("name"), Some(&Value::string("deprecated")));
assert_eq!(field.get("description"), Some(&Value::null()));
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(true)));
assert_eq!(field.get("deprecationReason"), Some(&Value::string("Deprecation reason")));
assert_eq!(
field.get("deprecationReason"),
Some(&Value::string("Deprecation reason"))
);
});
}
@ -175,7 +183,10 @@ fn introspect_interface_field_deprecated() {
assert_eq!(field.get("name"), Some(&Value::string("deprecated")));
assert_eq!(field.get("description"), Some(&Value::null()));
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(true)));
assert_eq!(field.get("deprecationReason"), Some(&Value::string("Deprecation reason")));
assert_eq!(
field.get("deprecationReason"),
Some(&Value::string("Deprecation reason"))
);
});
}
@ -183,9 +194,15 @@ fn introspect_interface_field_deprecated() {
fn introspect_object_field_deprecated_descr() {
run_field_info_query("Root", "deprecatedDescr", |field| {
assert_eq!(field.get("name"), Some(&Value::string("deprecatedDescr")));
assert_eq!(field.get("description"), Some(&Value::string("Field description")));
assert_eq!(
field.get("description"),
Some(&Value::string("Field description"))
);
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(true)));
assert_eq!(field.get("deprecationReason"), Some(&Value::string("Deprecation reason")));
assert_eq!(
field.get("deprecationReason"),
Some(&Value::string("Deprecation reason"))
);
});
}
@ -193,8 +210,14 @@ fn introspect_object_field_deprecated_descr() {
fn introspect_interface_field_deprecated_descr() {
run_field_info_query("Interface", "deprecatedDescr", |field| {
assert_eq!(field.get("name"), Some(&Value::string("deprecatedDescr")));
assert_eq!(field.get("description"), Some(&Value::string("Field description")));
assert_eq!(
field.get("description"),
Some(&Value::string("Field description"))
);
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(true)));
assert_eq!(field.get("deprecationReason"), Some(&Value::string("Deprecation reason")));
assert_eq!(
field.get("deprecationReason"),
Some(&Value::string("Deprecation reason"))
);
});
}

View file

@ -53,7 +53,6 @@ graphql_interface!(CustomName: () as "ACustomNamedInterface" |&self| {
instance_resolvers: |_| { Concrete => Some(Concrete) }
});
graphql_interface!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| {
field simple() -> i32 { 0 }
instance_resolvers: |_| { Concrete => Some(Concrete) }
@ -64,7 +63,6 @@ graphql_interface!(<T> WithGenerics<T>: () as "WithGenerics" |&self| {
instance_resolvers: |_| { Concrete => Some(Concrete) }
});
graphql_interface!(DescriptionFirst: () |&self| {
description: "A description"
@ -97,7 +95,6 @@ graphql_interface!(CommasWithTrailing: () |&self| {
description: "A description",
});
graphql_interface!(CommasOnMeta: () |&self| {
instance_resolvers: |_| { Concrete => Some(Concrete) }
description: "A description",
@ -105,7 +102,6 @@ graphql_interface!(CommasOnMeta: () |&self| {
field simple() -> i32 { 0 }
});
graphql_interface!(ResolversWithTrailingComma: () |&self| {
instance_resolvers: |_| { Concrete => Some(Concrete), }
description: "A description",
@ -132,7 +128,6 @@ graphql_object!(<'a> Root: () as "Root" |&self| {
});
fn run_type_info_query<F>(type_name: &str, f: F)
where
F: Fn(&OrderMap<String, Value>, &Vec<Value>) -> (),
@ -149,9 +144,8 @@ where
}
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let vars = vec![
("typeName".to_owned(), InputValue::string(type_name)),
].into_iter()
let vars = vec![("typeName".to_owned(), InputValue::string(type_name))]
.into_iter()
.collect();
let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
@ -180,12 +174,19 @@ where
#[test]
fn introspect_custom_name() {
run_type_info_query("ACustomNamedInterface", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("ACustomNamedInterface")));
assert_eq!(
object.get("name"),
Some(&Value::string("ACustomNamedInterface"))
);
assert_eq!(object.get("description"), Some(&Value::null()));
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}
@ -195,9 +196,13 @@ fn introspect_with_lifetime() {
assert_eq!(object.get("name"), Some(&Value::string("WithLifetime")));
assert_eq!(object.get("description"), Some(&Value::null()));
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}
@ -207,9 +212,13 @@ fn introspect_with_generics() {
assert_eq!(object.get("name"), Some(&Value::string("WithGenerics")));
assert_eq!(object.get("description"), Some(&Value::null()));
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}
@ -217,11 +226,18 @@ fn introspect_with_generics() {
fn introspect_description_first() {
run_type_info_query("DescriptionFirst", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("DescriptionFirst")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}
@ -229,11 +245,18 @@ fn introspect_description_first() {
fn introspect_fields_first() {
run_type_info_query("FieldsFirst", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("FieldsFirst")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}
@ -241,23 +264,40 @@ fn introspect_fields_first() {
fn introspect_interfaces_first() {
run_type_info_query("InterfacesFirst", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("InterfacesFirst")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}
#[test]
fn introspect_commas_with_trailing() {
run_type_info_query("CommasWithTrailing", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("CommasWithTrailing")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(
object.get("name"),
Some(&Value::string("CommasWithTrailing"))
);
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}
@ -265,22 +305,39 @@ fn introspect_commas_with_trailing() {
fn introspect_commas_on_meta() {
run_type_info_query("CommasOnMeta", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("CommasOnMeta")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}
#[test]
fn introspect_resolvers_with_trailing_comma() {
run_type_info_query("ResolversWithTrailingComma", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("ResolversWithTrailingComma")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(
object.get("name"),
Some(&Value::string("ResolversWithTrailingComma"))
);
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert!(fields.contains(&Value::object(vec![
("name", Value::string("simple")),
].into_iter().collect())));
assert!(
fields.contains(&Value::object(
vec![("name", Value::string("simple"))]
.into_iter()
.collect()
))
);
});
}

View file

@ -4,6 +4,3 @@ mod field;
mod object;
mod interface;
mod union;

View file

@ -5,7 +5,7 @@ use ast::InputValue;
use value::Value;
use schema::model::RootNode;
use types::scalars::EmptyMutation;
use executor::{FieldResult, Context};
use executor::{Context, FieldResult};
/*
@ -46,7 +46,6 @@ graphql_object!(CustomName: () as "ACustomNamedType" |&self| {
field simple() -> i32 { 0 }
});
graphql_object!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| {
field simple() -> i32 { 0 }
});
@ -55,7 +54,6 @@ graphql_object!(<T> WithGenerics<T>: () as "WithGenerics" |&self| {
field simple() -> i32 { 0 }
});
graphql_interface!(Interface: () |&self| {
field simple() -> i32 { 0 }
@ -96,7 +94,6 @@ graphql_object!(CommasWithTrailing: () |&self| {
description: "A description",
});
graphql_object!(CommasOnMeta: () |&self| {
interfaces: [Interface],
description: "A description",
@ -108,15 +105,25 @@ struct InnerContext;
impl Context for InnerContext {}
struct InnerType;
graphql_object!(InnerType: InnerContext |&self| {
});
graphql_object!(InnerType: InnerContext | &self | {});
struct CtxSwitcher;
graphql_object!(CtxSwitcher: InnerContext |&self| {
field ctx_switch_always(&executor) -> (&InnerContext, InnerType) { (executor.context(), InnerType) }
field ctx_switch_opt(&executor) -> Option<(&InnerContext, InnerType)> { Some((executor.context(), InnerType)) }
field ctx_switch_res(&executor) -> FieldResult<(&InnerContext, InnerType)> { Ok((executor.context(), InnerType)) }
field ctx_switch_res_opt(&executor) -> FieldResult<Option<(&InnerContext, InnerType)>> { Ok(Some((executor.context(), InnerType))) }
field ctx_switch_always(&executor) -> (&InnerContext, InnerType) {
(executor.context(), InnerType)
}
field ctx_switch_opt(&executor) -> Option<(&InnerContext, InnerType)> {
Some((executor.context(), InnerType))
}
field ctx_switch_res(&executor) -> FieldResult<(&InnerContext, InnerType)> {
Ok((executor.context(), InnerType))
}
field ctx_switch_res_opt(&executor) -> FieldResult<Option<(&InnerContext, InnerType)>> {
Ok(Some((executor.context(), InnerType)))
}
});
graphql_object!(<'a> Root: InnerContext as "Root" |&self| {
@ -135,7 +142,6 @@ graphql_object!(<'a> Root: InnerContext as "Root" |&self| {
field ctx_switcher() -> CtxSwitcher { CtxSwitcher {} }
});
fn run_type_info_query<F>(type_name: &str, f: F)
where
F: Fn(&OrderMap<String, Value>, &Vec<Value>) -> (),
@ -164,12 +170,12 @@ where
}
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<InnerContext>::new());
let vars = vec![
("typeName".to_owned(), InputValue::string(type_name)),
].into_iter()
let vars = vec![("typeName".to_owned(), InputValue::string(type_name))]
.into_iter()
.collect();
let (result, errs) = ::execute(doc, None, &schema, &vars, &InnerContext).expect("Execution failed");
let (result, errs) =
::execute(doc, None, &schema, &vars, &InnerContext).expect("Execution failed");
assert_eq!(errs, []);
@ -238,13 +244,22 @@ fn introspect_with_generics() {
fn introspect_description_first() {
run_type_info_query("DescriptionFirst", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("DescriptionFirst")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
Value::object(vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter().collect()),
])));
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert_eq!(
object.get("interfaces"),
Some(&Value::list(vec![
Value::object(
vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter()
.collect(),
),
]))
);
assert!(fields.contains(&graphql_value!({
"name": "simple",
@ -257,13 +272,22 @@ fn introspect_description_first() {
fn introspect_fields_first() {
run_type_info_query("FieldsFirst", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("FieldsFirst")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
Value::object(vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter().collect()),
])));
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert_eq!(
object.get("interfaces"),
Some(&Value::list(vec![
Value::object(
vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter()
.collect(),
),
]))
);
assert!(fields.contains(&graphql_value!({
"name": "simple",
@ -276,13 +300,22 @@ fn introspect_fields_first() {
fn introspect_interfaces_first() {
run_type_info_query("InterfacesFirst", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("InterfacesFirst")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
Value::object(vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter().collect()),
])));
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert_eq!(
object.get("interfaces"),
Some(&Value::list(vec![
Value::object(
vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter()
.collect(),
),
]))
);
assert!(fields.contains(&graphql_value!({
"name": "simple",
@ -294,14 +327,26 @@ fn introspect_interfaces_first() {
#[test]
fn introspect_commas_with_trailing() {
run_type_info_query("CommasWithTrailing", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("CommasWithTrailing")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
Value::object(vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter().collect()),
])));
assert_eq!(
object.get("name"),
Some(&Value::string("CommasWithTrailing"))
);
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert_eq!(
object.get("interfaces"),
Some(&Value::list(vec![
Value::object(
vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter()
.collect(),
),
]))
);
assert!(fields.contains(&graphql_value!({
"name": "simple",
@ -314,13 +359,22 @@ fn introspect_commas_with_trailing() {
fn introspect_commas_on_meta() {
run_type_info_query("CommasOnMeta", |object, fields| {
assert_eq!(object.get("name"), Some(&Value::string("CommasOnMeta")));
assert_eq!(object.get("description"), Some(&Value::string("A description")));
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
Value::object(vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter().collect()),
])));
assert_eq!(
object.get("description"),
Some(&Value::string("A description"))
);
assert_eq!(
object.get("interfaces"),
Some(&Value::list(vec![
Value::object(
vec![
("name", Value::string("Interface")),
("kind", Value::string("INTERFACE")),
].into_iter()
.collect(),
),
]))
);
assert!(fields.contains(&graphql_value!({
"name": "simple",

View file

@ -157,7 +157,13 @@ fn scalar_description_introspection() {
"#;
run_type_info_query(doc, |type_info| {
assert_eq!(type_info.get("name"), Some(&Value::string("ScalarDescription")));
assert_eq!(type_info.get("description"), Some(&Value::string("A sample scalar, represented as an integer")));
assert_eq!(
type_info.get("name"),
Some(&Value::string("ScalarDescription"))
);
assert_eq!(
type_info.get("description"),
Some(&Value::string("A sample scalar, represented as an integer"))
);
});
}

View file

@ -109,7 +109,6 @@ graphql_object!(<'a> Root: () as "Root" |&self| {
}
});
fn run_type_info_query<F>(type_name: &str, f: F)
where
F: Fn(&OrderMap<String, Value>, &Vec<Value>) -> (),
@ -126,9 +125,8 @@ where
}
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let vars = vec![
("typeName".to_owned(), InputValue::string(type_name)),
].into_iter()
let vars = vec![("typeName".to_owned(), InputValue::string(type_name))]
.into_iter()
.collect();
let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
@ -154,16 +152,19 @@ where
f(type_info, possible_types);
}
#[test]
fn introspect_custom_name() {
run_type_info_query("ACustomNamedUnion", |union, possible_types| {
assert_eq!(union.get("name"), Some(&Value::string("ACustomNamedUnion")));
assert_eq!(union.get("description"), Some(&Value::null()));
assert!(possible_types.contains(&Value::object(vec![
("name", Value::string("Concrete")),
].into_iter().collect())));
assert!(
possible_types.contains(&Value::object(
vec![("name", Value::string("Concrete"))]
.into_iter()
.collect()
))
);
});
}
@ -173,9 +174,13 @@ fn introspect_with_lifetime() {
assert_eq!(union.get("name"), Some(&Value::string("WithLifetime")));
assert_eq!(union.get("description"), Some(&Value::null()));
assert!(possible_types.contains(&Value::object(vec![
("name", Value::string("Concrete")),
].into_iter().collect())));
assert!(
possible_types.contains(&Value::object(
vec![("name", Value::string("Concrete"))]
.into_iter()
.collect()
))
);
});
}
@ -185,9 +190,13 @@ fn introspect_with_generics() {
assert_eq!(union.get("name"), Some(&Value::string("WithGenerics")));
assert_eq!(union.get("description"), Some(&Value::null()));
assert!(possible_types.contains(&Value::object(vec![
("name", Value::string("Concrete")),
].into_iter().collect())));
assert!(
possible_types.contains(&Value::object(
vec![("name", Value::string("Concrete"))]
.into_iter()
.collect()
))
);
});
}
@ -195,11 +204,18 @@ fn introspect_with_generics() {
fn introspect_description_first() {
run_type_info_query("DescriptionFirst", |union, possible_types| {
assert_eq!(union.get("name"), Some(&Value::string("DescriptionFirst")));
assert_eq!(union.get("description"), Some(&Value::string("A description")));
assert_eq!(
union.get("description"),
Some(&Value::string("A description"))
);
assert!(possible_types.contains(&Value::object(vec![
("name", Value::string("Concrete")),
].into_iter().collect())));
assert!(
possible_types.contains(&Value::object(
vec![("name", Value::string("Concrete"))]
.into_iter()
.collect()
))
);
});
}
@ -207,34 +223,61 @@ fn introspect_description_first() {
fn introspect_resolvers_first() {
run_type_info_query("ResolversFirst", |union, possible_types| {
assert_eq!(union.get("name"), Some(&Value::string("ResolversFirst")));
assert_eq!(union.get("description"), Some(&Value::string("A description")));
assert_eq!(
union.get("description"),
Some(&Value::string("A description"))
);
assert!(possible_types.contains(&Value::object(vec![
("name", Value::string("Concrete")),
].into_iter().collect())));
assert!(
possible_types.contains(&Value::object(
vec![("name", Value::string("Concrete"))]
.into_iter()
.collect()
))
);
});
}
#[test]
fn introspect_commas_with_trailing() {
run_type_info_query("CommasWithTrailing", |union, possible_types| {
assert_eq!(union.get("name"), Some(&Value::string("CommasWithTrailing")));
assert_eq!(union.get("description"), Some(&Value::string("A description")));
assert_eq!(
union.get("name"),
Some(&Value::string("CommasWithTrailing"))
);
assert_eq!(
union.get("description"),
Some(&Value::string("A description"))
);
assert!(possible_types.contains(&Value::object(vec![
("name", Value::string("Concrete")),
].into_iter().collect())));
assert!(
possible_types.contains(&Value::object(
vec![("name", Value::string("Concrete"))]
.into_iter()
.collect()
))
);
});
}
#[test]
fn introspect_resolvers_with_trailing_comma() {
run_type_info_query("ResolversWithTrailingComma", |union, possible_types| {
assert_eq!(union.get("name"), Some(&Value::string("ResolversWithTrailingComma")));
assert_eq!(union.get("description"), Some(&Value::string("A description")));
assert_eq!(
union.get("name"),
Some(&Value::string("ResolversWithTrailingComma"))
);
assert_eq!(
union.get("description"),
Some(&Value::string("A description"))
);
assert!(possible_types.contains(&Value::object(vec![
("name", Value::string("Concrete")),
].into_iter().collect())));
assert!(
possible_types.contains(&Value::object(
vec![("name", Value::string("Concrete"))]
.into_iter()
.collect()
))
);
});
}

View file

@ -40,7 +40,8 @@ macro_rules! graphql_union {
(
@ gather_meta,
($reg:expr, $acc:expr, $descr:expr),
instance_resolvers: | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
instance_resolvers: | $ctxtvar:pat
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
) => {
$acc = vec![
$(
@ -56,7 +57,8 @@ macro_rules! graphql_union {
(
@ concrete_type_name,
($outname:tt, $ctxtarg:ident, $ctxttype:ty),
instance_resolvers: | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
instance_resolvers: | $ctxtvar:pat
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
) => {
let $ctxtvar = &$ctxtarg;
@ -74,7 +76,8 @@ macro_rules! graphql_union {
(
@ resolve_into_type,
($outname:tt, $typenamearg:ident, $execarg:ident, $ctxttype:ty),
instance_resolvers: | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
instance_resolvers: | $ctxtvar:pat
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
) => {
let $ctxtvar = &$execarg.context();

View file

@ -32,9 +32,9 @@ fn parse_definition<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Def
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::Name("fragment") => Ok(Definition::Fragment(try!(parse_fragment_definition(
parser
)))),
_ => Err(parser.next()?.map(ParseError::UnexpectedToken)),
}
}
@ -237,13 +237,12 @@ 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(),
}
try!(parser.delimited_nonempty_list(
&Token::ParenOpen,
parse_argument,
&Token::ParenClose
)).map(|args| Arguments {
items: args.into_iter().map(|s| s.item).collect(),
}),
))
}
@ -282,10 +281,8 @@ fn parse_variable_definitions<'a>(
&Token::ParenOpen,
parse_variable_definition,
&Token::ParenClose
)).map(|defs| {
VariableDefinitions {
items: defs.into_iter().map(|s| s.item).collect(),
}
)).map(|defs| VariableDefinitions {
items: defs.into_iter().map(|s| s.item).collect(),
}),
))
}

View file

@ -127,9 +127,8 @@ impl<'a> Lexer<'a> {
let start_pos = self.position.clone();
self.next_char().expect(
"Internal error in GraphQL lexer: emit_single_char reached EOF",
);
self.next_char()
.expect("Internal error in GraphQL lexer: emit_single_char reached EOF");
Spanning::single_width(&start_pos, t)
}
@ -345,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 = try!(
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(
@ -392,10 +391,12 @@ impl<'a> Lexer<'a> {
let mantissa = frac_part
.map(|f| f as f64)
.map(|frac| if frac > 0f64 {
frac / 10f64.powf(frac.log10().floor() + 1f64)
} else {
0f64
.map(|frac| {
if frac > 0f64 {
frac / 10f64.powf(frac.log10().floor() + 1f64)
} else {
0f64
}
})
.map(|m| if int_part < 0 { -m } else { m });
@ -472,9 +473,8 @@ impl<'a> Lexer<'a> {
}
}
i32::from_str_radix(&self.source[start_idx..end_idx + 1], 10).map_err(|_| {
Spanning::zero_width(&start_pos, LexerError::InvalidNumber)
})
i32::from_str_radix(&self.source[start_idx..end_idx + 1], 10)
.map_err(|_| Spanning::zero_width(&start_pos, LexerError::InvalidNumber))
}
}

View file

@ -171,10 +171,12 @@ impl<'a> Parser<'a> {
Spanning {
item: Token::Name(_),
..
} => Ok(self.next()?.map(|token| if let Token::Name(name) = token {
name
} else {
panic!("Internal parse error in `expect_name`");
} => Ok(self.next()?.map(|token| {
if let Token::Name(name) = token {
name
} else {
panic!("Internal parse error in `expect_name`");
}
})),
Spanning {
item: Token::EndOfFile,

View file

@ -4,7 +4,6 @@ use ast::InputValue;
use parser::{Lexer, Parser, SourcePosition, Spanning};
use parser::value::parse_value_literal;
fn parse_value(s: &str) -> Spanning<InputValue> {
let mut lexer = Lexer::new(s);
let mut parser = Parser::new(&mut lexer).expect(&format!("Lexer error on input {:#?}", s));

View file

@ -33,10 +33,12 @@ pub fn parse_value_literal<'a>(
Spanning {
item: Token::String(_),
..
} => Ok(parser.next()?.map(|t| if let Token::String(s) = t {
InputValue::string(s)
} else {
panic!("Internal parser error");
} => Ok(parser.next()?.map(|t| {
if let Token::String(s) = t {
InputValue::string(s)
} else {
panic!("Internal parser error");
}
})),
Spanning {
item: Token::Name("true"),
@ -53,38 +55,30 @@ pub fn parse_value_literal<'a>(
Spanning {
item: Token::Name(name),
..
} => Ok(
parser
.next()?
.map(|_| InputValue::enum_value(name.to_owned())),
),
} => Ok(parser
.next()?
.map(|_| InputValue::enum_value(name.to_owned()))),
_ => Err(parser.next()?.map(ParseError::UnexpectedToken)),
}
}
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(try!(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(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())))
}
fn parse_object_field<'a>(

View file

@ -8,85 +8,62 @@ 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
@ -95,59 +72,40 @@ 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
@ -174,12 +132,12 @@ impl<'a> MetaType<'a> {
/// Lists, non-null wrappers, and placeholders don't have names.
pub fn name(&self) -> Option<&str> {
match *self {
MetaType::Scalar(ScalarMeta { ref name, .. }) |
MetaType::Object(ObjectMeta { ref name, .. }) |
MetaType::Enum(EnumMeta { ref name, .. }) |
MetaType::Interface(InterfaceMeta { ref name, .. }) |
MetaType::Union(UnionMeta { ref name, .. }) |
MetaType::InputObject(InputObjectMeta { ref name, .. }) => Some(name),
MetaType::Scalar(ScalarMeta { ref name, .. })
| MetaType::Object(ObjectMeta { ref name, .. })
| MetaType::Enum(EnumMeta { ref name, .. })
| MetaType::Interface(InterfaceMeta { ref name, .. })
| MetaType::Union(UnionMeta { ref name, .. })
| MetaType::InputObject(InputObjectMeta { ref name, .. }) => Some(name),
_ => None,
}
}
@ -191,20 +149,20 @@ impl<'a> MetaType<'a> {
match *self {
MetaType::Scalar(ScalarMeta {
ref description, ..
}) |
MetaType::Object(ObjectMeta {
})
| MetaType::Object(ObjectMeta {
ref description, ..
}) |
MetaType::Enum(EnumMeta {
})
| MetaType::Enum(EnumMeta {
ref description, ..
}) |
MetaType::Interface(InterfaceMeta {
})
| MetaType::Interface(InterfaceMeta {
ref description, ..
}) |
MetaType::Union(UnionMeta {
})
| MetaType::Union(UnionMeta {
ref description, ..
}) |
MetaType::InputObject(InputObjectMeta {
})
| MetaType::InputObject(InputObjectMeta {
ref description, ..
}) => description.as_ref(),
_ => None,
@ -234,8 +192,8 @@ impl<'a> MetaType<'a> {
/// Only objects and interfaces have fields. This method always returns `None` for other types.
pub fn field_by_name(&self, name: &str) -> Option<&Field> {
match *self {
MetaType::Object(ObjectMeta { ref fields, .. }) |
MetaType::Interface(InterfaceMeta { ref fields, .. }) => {
MetaType::Object(ObjectMeta { ref fields, .. })
| MetaType::Interface(InterfaceMeta { ref fields, .. }) => {
fields.iter().find(|f| f.name == name)
}
_ => None,
@ -257,12 +215,12 @@ impl<'a> MetaType<'a> {
/// Construct a `Type` literal instance based on the metadata
pub fn as_type(&self) -> Type<'a> {
match *self {
MetaType::Scalar(ScalarMeta { ref name, .. }) |
MetaType::Object(ObjectMeta { ref name, .. }) |
MetaType::Enum(EnumMeta { ref name, .. }) |
MetaType::Interface(InterfaceMeta { ref name, .. }) |
MetaType::Union(UnionMeta { ref name, .. }) |
MetaType::InputObject(InputObjectMeta { ref name, .. }) => {
MetaType::Scalar(ScalarMeta { ref name, .. })
| MetaType::Object(ObjectMeta { ref name, .. })
| MetaType::Enum(EnumMeta { ref name, .. })
| MetaType::Interface(InterfaceMeta { ref name, .. })
| MetaType::Union(UnionMeta { ref name, .. })
| MetaType::InputObject(InputObjectMeta { ref name, .. }) => {
Type::NonNullNamed(name.clone())
}
MetaType::List(ListMeta { ref of_type }) => {
@ -287,11 +245,11 @@ impl<'a> MetaType<'a> {
match *self {
MetaType::Scalar(ScalarMeta {
ref try_parse_fn, ..
}) |
MetaType::Enum(EnumMeta {
})
| MetaType::Enum(EnumMeta {
ref try_parse_fn, ..
}) |
MetaType::InputObject(InputObjectMeta {
})
| MetaType::InputObject(InputObjectMeta {
ref try_parse_fn, ..
}) => Some(try_parse_fn),
_ => None,
@ -345,7 +303,9 @@ impl<'a> ScalarMeta<'a> {
ScalarMeta {
name: name,
description: None,
try_parse_fn: Box::new(|v: &InputValue| <T as FromInputValue>::from_input_value(v).is_some()),
try_parse_fn: Box::new(|v: &InputValue| {
<T as FromInputValue>::from_input_value(v).is_some()
}),
}
}
@ -431,7 +391,9 @@ impl<'a> EnumMeta<'a> {
name: name,
description: None,
values: values.to_vec(),
try_parse_fn: Box::new(|v: &InputValue| <T as FromInputValue>::from_input_value(v).is_some()),
try_parse_fn: Box::new(|v: &InputValue| {
<T as FromInputValue>::from_input_value(v).is_some()
}),
}
}
@ -510,7 +472,9 @@ impl<'a> InputObjectMeta<'a> {
name: name,
description: None,
input_fields: input_fields.to_vec(),
try_parse_fn: Box::new(|v: &InputValue| <T as FromInputValue>::from_input_value(v).is_some()),
try_parse_fn: Box::new(|v: &InputValue| {
<T as FromInputValue>::from_input_value(v).is_some()
}),
}
}

View file

@ -13,16 +13,11 @@ use schema::meta::{Argument, InterfaceMeta, MetaType, ObjectMeta, PlaceholderMet
/// 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
@ -55,12 +50,9 @@ 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>
@ -277,9 +269,9 @@ impl<'a> SchemaType<'a> {
}
pub fn is_possible_type(&self, abstract_type: &MetaType, possible_type: &MetaType) -> bool {
self.possible_types(abstract_type).into_iter().any(|t| {
(t as *const MetaType) == (possible_type as *const MetaType)
})
self.possible_types(abstract_type)
.into_iter()
.any(|t| (t as *const MetaType) == (possible_type as *const MetaType))
}
pub fn is_subtype<'b>(&self, sub_type: &Type<'b>, super_type: &Type<'b>) -> bool {
@ -290,14 +282,14 @@ impl<'a> SchemaType<'a> {
}
match (super_type, sub_type) {
(&NonNullNamed(ref super_name), &NonNullNamed(ref sub_name)) |
(&Named(ref super_name), &Named(ref sub_name)) |
(&Named(ref super_name), &NonNullNamed(ref sub_name)) => {
(&NonNullNamed(ref super_name), &NonNullNamed(ref sub_name))
| (&Named(ref super_name), &Named(ref sub_name))
| (&Named(ref super_name), &NonNullNamed(ref sub_name)) => {
self.is_named_subtype(sub_name, super_name)
}
(&NonNullList(ref super_inner), &NonNullList(ref sub_inner)) |
(&List(ref super_inner), &List(ref sub_inner)) |
(&List(ref super_inner), &NonNullList(ref sub_inner)) => {
(&NonNullList(ref super_inner), &NonNullList(ref sub_inner))
| (&List(ref super_inner), &List(ref sub_inner))
| (&List(ref super_inner), &NonNullList(ref sub_inner)) => {
self.is_subtype(sub_inner, super_inner)
}
_ => false,

View file

@ -142,11 +142,15 @@ graphql_object!(<'a> TypeType<'a>: SchemaType<'a> as "__Type" |&self| {
.filter_map(|tn| schema.type_by_name(tn))
.collect())
}
TypeType::Concrete(&MetaType::Interface(InterfaceMeta { name: ref iface_name, .. })) => {
TypeType::Concrete(&MetaType::Interface(InterfaceMeta{name: ref iface_name, .. })) => {
Some(schema.concrete_type_list()
.iter()
.filter_map(|&ct|
if let MetaType::Object(ObjectMeta { ref name, ref interface_names, .. }) = *ct {
if let MetaType::Object(ObjectMeta{
ref name,
ref interface_names,
..
}) = *ct {
if interface_names.contains(&iface_name.to_string()) {
schema.type_by_name(name)
} else { None }
@ -232,7 +236,6 @@ graphql_object!(EnumValue: () as "__EnumValue" |&self| {
}
});
graphql_object!(<'a> DirectiveType<'a>: SchemaType<'a> as "__Directive" |&self| {
field name() -> &String {
&self.name
@ -270,4 +273,3 @@ graphql_object!(<'a> DirectiveType<'a>: SchemaType<'a> as "__Directive" |&self|
self.locations.contains(&DirectiveLocation::Field)
}
});

View file

@ -5,8 +5,7 @@ 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,
}

View file

@ -83,7 +83,6 @@ graphql_object!(<'a> &'a Droid: Database as "Droid" |&self| {
}
});
graphql_object!(Database: Database as "Query" |&self| {
description: "The root query object of the schema"

View file

@ -328,7 +328,8 @@ fn resolve_selection_set_into<T, CtxT>(
selection_set: &[Selection],
executor: &Executor<CtxT>,
result: &mut OrderMap<String, Value>,
) -> bool where
) -> bool
where
T: GraphQLType<Context = CtxT>,
{
let meta_type = executor
@ -441,7 +442,8 @@ fn resolve_selection_set_into<T, CtxT>(
let sub_exec = executor.type_sub_executor(
fragment.type_condition.as_ref().map(|c| c.item),
Some(&fragment.selection_set[..]));
Some(&fragment.selection_set[..]),
);
if let Some(ref type_condition) = fragment.type_condition {
let sub_result = instance.resolve_into_type(
@ -472,7 +474,7 @@ fn resolve_selection_set_into<T, CtxT>(
}
}
}
true
}
@ -491,8 +493,8 @@ fn is_excluded(directives: &Option<Vec<Spanning<Directive>>>, vars: &Variables)
.next()
.unwrap();
if (directive.name.item == "skip" && condition) ||
(directive.name.item == "include" && !condition)
if (directive.name.item == "skip" && condition)
|| (directive.name.item == "include" && !condition)
{
return true;
}

View file

@ -152,9 +152,15 @@ where
}
}
fn resolve_into_list<T: GraphQLType, I: Iterator<Item=T>>(executor: &Executor<T::Context>, info: &T::TypeInfo, iter: I) -> Value {
let stop_on_null = executor.current_type()
.list_contents().expect("Current type is not a list type")
fn resolve_into_list<T: GraphQLType, I: Iterator<Item = T>>(
executor: &Executor<T::Context>,
info: &T::TypeInfo,
iter: I,
) -> Value {
let stop_on_null = executor
.current_type()
.list_contents()
.expect("Current type is not a list type")
.is_non_null();
let mut result = Vec::new();
@ -169,4 +175,4 @@ fn resolve_into_list<T: GraphQLType, I: Iterator<Item=T>>(executor: &Executor<T:
}
Value::list(result)
}
}

View file

@ -44,7 +44,6 @@ graphql_scalar!(ID as "ID" {
}
});
graphql_scalar!(String as "String" {
resolve(&self) -> Value {
Value::string(self)
@ -58,7 +57,6 @@ graphql_scalar!(String as "String" {
}
});
impl<'a> GraphQLType for &'a str {
type Context = ();
type TypeInfo = ();
@ -82,8 +80,6 @@ impl<'a> ToInputValue for &'a str {
}
}
graphql_scalar!(bool as "Boolean" {
resolve(&self) -> Value {
Value::boolean(*self)
@ -97,7 +93,6 @@ graphql_scalar!(bool as "Boolean" {
}
});
graphql_scalar!(i32 as "Int" {
resolve(&self) -> Value {
Value::int(*self)
@ -111,7 +106,6 @@ graphql_scalar!(i32 as "Int" {
}
});
graphql_scalar!(f64 as "Float" {
resolve(&self) -> Value {
Value::float(*self)
@ -126,7 +120,6 @@ graphql_scalar!(f64 as "Float" {
}
});
impl GraphQLType for () {
type Context = ();
type TypeInfo = ();
@ -146,7 +139,6 @@ impl FromInputValue for () {
}
}
/// Utility type to define read-only schemas
///
/// If you instantiate `RootNode` with this as the mutation, no mutation will be

View file

@ -31,26 +31,29 @@ pub fn is_valid_literal_value(
match *arg_value {
InputValue::Null | InputValue::Variable(_) => true,
ref v @ InputValue::Int(_) |
ref v @ InputValue::Float(_) |
ref v @ InputValue::String(_) |
ref v @ InputValue::Boolean(_) |
ref v @ InputValue::Enum(_) => if let Some(parse_fn) = t.input_value_parse_fn() {
ref v @ InputValue::Int(_)
| ref v @ InputValue::Float(_)
| ref v @ InputValue::String(_)
| ref v @ InputValue::Boolean(_)
| ref v @ InputValue::Enum(_) => if let Some(parse_fn) = t.input_value_parse_fn() {
parse_fn(v)
} else {
false
},
InputValue::List(_) => false,
InputValue::Object(ref obj) => if let MetaType::InputObject(InputObjectMeta {
ref input_fields, ..
ref input_fields,
..
}) = *t
{
let mut remaining_required_fields = input_fields
.iter()
.filter_map(|f| if f.arg_type.is_non_null() {
Some(&f.name)
} else {
None
.filter_map(|f| {
if f.arg_type.is_non_null() {
Some(&f.name)
} else {
None
}
})
.collect::<HashSet<_>>();

View file

@ -277,9 +277,7 @@ fn push_unification_error<'a>(
errors.push(RuleError::new(
&format!(
r#"Variable "${}" got invalid value. {}{}."#,
var_name,
path,
message,
var_name, path, message,
),
&[var_pos.clone()],
));

View file

@ -60,12 +60,10 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
fn error_message(arg_name: &str, type_name: &str) -> String {
format!(
"Invalid value for argument \"{}\", expected type \"{}\"",
arg_name,
type_name
arg_name, type_name
)
}
#[cfg(test)]
mod tests {
use super::{error_message, factory};

View file

@ -43,16 +43,14 @@ impl<'a> Visitor<'a> for DefaultValuesOfCorrectType {
fn type_error_message(arg_name: &str, type_name: &str) -> String {
format!(
"Invalid default value for argument \"{}\", expected type \"{}\"",
arg_name,
type_name
arg_name, type_name
)
}
fn non_null_error_message(arg_name: &str, type_name: &str) -> String {
format!(
"Argument \"{}\" has type \"{}\" and is not nullable, so it't can't have a default value",
arg_name,
type_name
arg_name, type_name
)
}

View file

@ -17,7 +17,6 @@ impl<'a> Visitor<'a> for FieldsOnCorrectType {
let type_name = parent_type.name().unwrap_or("<unknown>");
if parent_type.field_by_name(field_name.item).is_none() {
match *parent_type {
MetaType::Union(..) => {
// You can query for `__typename` on a union,

View file

@ -55,8 +55,7 @@ fn error_message(fragment_name: Option<&str>, on_type: &str) -> String {
if let Some(name) = fragment_name {
format!(
r#"Fragment "{}" cannot condition non composite type "{}"#,
name,
on_type
name, on_type
)
} else {
format!(

View file

@ -23,14 +23,14 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
ctx: &mut ValidatorContext<'a>,
directive: &'a Spanning<Directive>,
) {
self.current_args = ctx.schema.directive_by_name(directive.item.name.item).map(
|d| {
self.current_args = ctx.schema
.directive_by_name(directive.item.name.item)
.map(|d| {
(
ArgumentPosition::Directive(directive.item.name.item),
&d.arguments,
)
},
);
});
}
fn exit_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Directive>) {
@ -84,17 +84,14 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
fn field_error_message(arg_name: &str, field_name: &str, type_name: &str) -> String {
format!(
r#"Unknown argument "{}" on field "{}" of type "{}""#,
arg_name,
field_name,
type_name
arg_name, field_name, type_name
)
}
fn directive_error_message(arg_name: &str, directive_name: &str) -> String {
format!(
r#"Unknown argument "{}" on directive "{}""#,
arg_name,
directive_name
arg_name, directive_name
)
}

View file

@ -132,8 +132,7 @@ fn unknown_error_message(directive_name: &str) -> String {
fn misplaced_error_message(directive_name: &str, location: &DirectiveLocation) -> String {
format!(
r#"Directive "{}" may not be used on {}"#,
directive_name,
location
directive_name, location
)
}

View file

@ -150,8 +150,7 @@ fn error_message(var_name: &str, op_name: Option<&str>) -> String {
if let Some(op_name) = op_name {
format!(
r#"Variable "${}" is not defined by operation "{}""#,
var_name,
op_name
var_name, op_name
)
} else {
format!(r#"Variable "${}" is not defined"#, var_name)

View file

@ -140,8 +140,7 @@ fn error_message(var_name: &str, op_name: Option<&str>) -> String {
if let Some(op_name) = op_name {
format!(
r#"Variable "${}" is not defined by operation "{}""#,
var_name,
op_name
var_name, op_name
)
} else {
format!(r#"Variable "${}" is not defined"#, var_name)

View file

@ -204,18 +204,21 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
};
{
if self.compared_fragments
.borrow()
.contains(fragment_name1, fragment_name2, mutually_exclusive)
{
if self.compared_fragments.borrow().contains(
fragment_name1,
fragment_name2,
mutually_exclusive,
) {
return;
}
}
{
self.compared_fragments
.borrow_mut()
.insert(fragment_name1, fragment_name2, mutually_exclusive);
self.compared_fragments.borrow_mut().insert(
fragment_name1,
fragment_name2,
mutually_exclusive,
);
}
let (field_map1, fragment_names1) =
@ -338,9 +341,9 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
let AstAndDef(ref parent_type1, ast1, ref def1) = *field1;
let AstAndDef(ref parent_type2, ast2, ref def2) = *field2;
let mutually_exclusive = parents_mutually_exclusive ||
(parent_type1 != parent_type2 && self.is_object_type(ctx, *parent_type1) &&
self.is_object_type(ctx, *parent_type2));
let mutually_exclusive = parents_mutually_exclusive
|| (parent_type1 != parent_type2 && self.is_object_type(ctx, *parent_type1)
&& self.is_object_type(ctx, *parent_type2));
if !mutually_exclusive {
let name1 = &ast1.item.name.item;
@ -350,9 +353,10 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
return Some(Conflict(
ConflictReason(
response_name.to_owned(),
ConflictReasonMessage::Message(
format!("{} and {} are different fields", name1, name2),
),
ConflictReasonMessage::Message(format!(
"{} and {} are different fields",
name1, name2
)),
),
vec![ast1.start.clone()],
vec![ast2.start.clone()],
@ -379,9 +383,10 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
return Some(Conflict(
ConflictReason(
response_name.to_owned(),
ConflictReasonMessage::Message(
format!("they return conflicting types {} and {}", t1, t2),
),
ConflictReasonMessage::Message(format!(
"they return conflicting types {} and {}",
t1, t2
)),
),
vec![ast1.start.clone()],
vec![ast2.start.clone()],
@ -389,8 +394,7 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
}
}
if let (&Some(ref s1), &Some(ref s2)) =
(&ast1.item.selection_set, &ast2.item.selection_set)
if let (&Some(ref s1), &Some(ref s2)) = (&ast1.item.selection_set, &ast2.item.selection_set)
{
let conflicts = self.find_conflicts_between_sub_selection_sets(
mutually_exclusive,
@ -506,17 +510,17 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
fn is_type_conflict(&self, ctx: &ValidatorContext<'a>, t1: &Type, t2: &Type) -> bool {
match (t1, t2) {
(&Type::List(ref inner1), &Type::List(ref inner2)) |
(&Type::NonNullList(ref inner1), &Type::NonNullList(ref inner2)) => {
(&Type::List(ref inner1), &Type::List(ref inner2))
| (&Type::NonNullList(ref inner1), &Type::NonNullList(ref inner2)) => {
self.is_type_conflict(ctx, inner1, inner2)
}
(&Type::NonNullNamed(ref n1), &Type::NonNullNamed(ref n2)) |
(&Type::Named(ref n1), &Type::Named(ref n2)) => {
(&Type::NonNullNamed(ref n1), &Type::NonNullNamed(ref n2))
| (&Type::Named(ref n1), &Type::Named(ref n2)) => {
let ct1 = ctx.schema.concrete_type_by_name(n1);
let ct2 = ctx.schema.concrete_type_by_name(n2);
if ct1.map(|ct| ct.is_leaf()).unwrap_or(false) ||
ct2.map(|ct| ct.is_leaf()).unwrap_or(false)
if ct1.map(|ct| ct.is_leaf()).unwrap_or(false)
|| ct2.map(|ct| ct.is_leaf()).unwrap_or(false)
{
n1 != n2
} else {
@ -1755,9 +1759,7 @@ mod tests {
RuleError::new(
&error_message(
"scalar",
&Message(
"they return conflicting types String! and String".to_owned(),
),
&Message("they return conflicting types String! and String".to_owned()),
),
&[
SourcePosition::new(100, 4, 18),

View file

@ -78,16 +78,13 @@ fn error_message(frag_name: Option<&str>, parent_type_name: &str, frag_type: &st
format!(
"Fragment \"{}\" cannot be spread here as objects of type \
\"{}\" can never be of type \"{}\"",
frag_name,
parent_type_name,
frag_type
frag_name, parent_type_name, frag_type
)
} else {
format!(
"Fragment cannot be spread here as objects of type \"{}\" \
can never be of type \"{}\"",
parent_type_name,
frag_type
parent_type_name, frag_type
)
}
}

View file

@ -20,8 +20,8 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
}) = ctx.parent_type().and_then(|t| t.field_by_name(field_name))
{
for meta_arg in meta_args {
if meta_arg.arg_type.is_non_null() &&
field
if meta_arg.arg_type.is_non_null()
&& field
.item
.arguments
.as_ref()
@ -54,8 +54,8 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
}) = ctx.schema.directive_by_name(directive_name)
{
for meta_arg in meta_args {
if meta_arg.arg_type.is_non_null() &&
directive
if meta_arg.arg_type.is_non_null()
&& directive
.item
.arguments
.as_ref()
@ -79,18 +79,14 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
fn field_error_message(field_name: &str, arg_name: &str, type_name: &str) -> String {
format!(
r#"Field "{}" argument "{}" of type "{}" is required but not provided"#,
field_name,
arg_name,
type_name
field_name, arg_name, type_name
)
}
fn directive_error_message(directive_name: &str, arg_name: &str, type_name: &str) -> String {
format!(
r#"Directive "@{}" argument "{}" of type "{}" is required but not provided"#,
directive_name,
arg_name,
type_name
directive_name, arg_name, type_name
)
}

View file

@ -39,8 +39,7 @@ impl<'a> Visitor<'a> for ScalarLeafs {
fn no_allowed_error_message(field_name: &str, type_name: &str) -> String {
format!(
r#"Field "{}" must not have a selection since type {} has no subfields"#,
field_name,
type_name
field_name, type_name
)
}

View file

@ -30,8 +30,7 @@ impl<'a> Visitor<'a> for UniqueVariableNames {
fn error_message(var_name: &str, type_name: &str) -> String {
format!(
"Variable \"{}\" cannot be of non-input type \"{}\"",
var_name,
type_name
var_name, type_name
)
}

View file

@ -148,9 +148,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
fn error_message(var_name: &str, type_name: &str, expected_type_name: &str) -> String {
format!(
"Variable \"{}\" of type \"{}\" used in position expecting type \"{}\"",
var_name,
type_name,
expected_type_name
var_name, type_name, expected_type_name
)
}

View file

@ -236,10 +236,7 @@ impl GraphQLType for Cat {
registry
.build_object_type::<Self>(i, fields)
.interfaces(&[
registry.get_type::<Being>(i),
registry.get_type::<Pet>(i),
])
.interfaces(&[registry.get_type::<Being>(i), registry.get_type::<Pet>(i)])
.into_meta()
}
}
@ -434,9 +431,7 @@ impl GraphQLType for ComplicatedArgs {
.argument(registry.arg::<Option<ID>>("idArg", i)),
registry
.field::<Option<String>>("stringListArgField", i)
.argument(
registry.arg::<Option<Vec<Option<String>>>>("stringListArg", i),
),
.argument(registry.arg::<Option<Vec<Option<String>>>>("stringListArg", i)),
registry
.field::<Option<String>>("complexArgField", i)
.argument(registry.arg::<Option<ComplexInput>>("complexArg", i)),

View file

@ -3,7 +3,6 @@ use ast::{Directive, Document, Field, Fragment, FragmentSpread, InlineFragment,
use parser::Spanning;
use validation::ValidatorContext;
#[doc(hidden)]
pub trait Visitor<'a> {
fn enter_document(&mut self, _: &mut ValidatorContext<'a>, _: &'a Document) {}

View file

@ -22,26 +22,29 @@ fn visit_definitions<'a, V: Visitor<'a>>(
for def in d {
let def_type = match *def {
Definition::Fragment(Spanning {
item: Fragment {
type_condition: Spanning { item: name, .. },
..
},
item:
Fragment {
type_condition: Spanning { item: name, .. },
..
},
..
}) => Some(Type::NonNullNamed(Cow::Borrowed(name))),
Definition::Operation(Spanning {
item: Operation {
operation_type: OperationType::Query,
..
},
item:
Operation {
operation_type: OperationType::Query,
..
},
..
}) => Some(Type::NonNullNamed(Cow::Borrowed(
ctx.schema.concrete_query_type().name().unwrap(),
))),
Definition::Operation(Spanning {
item: Operation {
operation_type: OperationType::Mutation,
..
},
item:
Operation {
operation_type: OperationType::Mutation,
..
},
..
}) => ctx.schema
.concrete_mutation_type()
@ -284,8 +287,10 @@ fn visit_input_value<'a, V: Visitor<'a>>(
_ => None,
});
ctx.with_pushed_input_type(inner_type.as_ref(), |ctx| for value in ls {
visit_input_value(v, ctx, value);
ctx.with_pushed_input_type(inner_type.as_ref(), |ctx| {
for value in ls {
visit_input_value(v, ctx, value);
}
})
}
_ => (),

View file

@ -125,13 +125,18 @@ impl ToInputValue for Value {
Value::Float(f) => InputValue::Float(f),
Value::String(ref s) => InputValue::String(s.clone()),
Value::Boolean(b) => InputValue::Boolean(b),
Value::List(ref l) => {
InputValue::List(l.iter().map(|x| Spanning::unlocated(x.to_input_value())).collect())
}
Value::List(ref l) => InputValue::List(
l.iter()
.map(|x| Spanning::unlocated(x.to_input_value()))
.collect(),
),
Value::Object(ref o) => InputValue::Object(
o.iter()
.map(|(k, v)| {
(Spanning::unlocated(k.clone()), Spanning::unlocated(v.to_input_value()))
(
Spanning::unlocated(k.clone()),
Spanning::unlocated(v.to_input_value()),
)
})
.collect(),
),
@ -169,11 +174,14 @@ impl From<f64> for Value {
}
}
impl<T> From<Option<T>> for Value where Value: From<T> {
impl<T> From<Option<T>> for Value
where
Value: From<T>,
{
fn from(v: Option<T>) -> Value {
match v {
Some(v) => Value::from(v),
None => Value::null()
None => Value::null(),
}
}
}
@ -215,52 +223,34 @@ mod tests {
#[test]
fn value_macro_string() {
assert_eq!(
graphql_value!("test"),
Value::string("test")
);
assert_eq!(graphql_value!("test"), Value::string("test"));
}
#[test]
fn value_macro_int() {
assert_eq!(
graphql_value!(123),
Value::int(123)
);
assert_eq!(graphql_value!(123), Value::int(123));
}
#[test]
fn value_macro_float() {
assert_eq!(
graphql_value!(123.5),
Value::float(123.5)
);
assert_eq!(graphql_value!(123.5), Value::float(123.5));
}
#[test]
fn value_macro_boolean() {
assert_eq!(
graphql_value!(false),
Value::boolean(false)
);
assert_eq!(graphql_value!(false), Value::boolean(false));
}
#[test]
fn value_macro_option() {
assert_eq!(
graphql_value!(Some("test")),
Value::string("test")
);
assert_eq!(
graphql_value!(None),
Value::null()
);
assert_eq!(graphql_value!(Some("test")), Value::string("test"));
assert_eq!(graphql_value!(None), Value::null());
}
#[test]
fn value_macro_list() {
assert_eq!(
graphql_value!([ 123, "Test", false ]),
graphql_value!([123, "Test", false]),
Value::list(vec![
Value::int(123),
Value::string("Test"),
@ -268,10 +258,10 @@ mod tests {
])
);
assert_eq!(
graphql_value!([ 123, [ 456 ], 789 ]),
graphql_value!([123, [456], 789]),
Value::list(vec![
Value::int(123),
Value::list(vec![ Value::int(456) ]),
Value::list(vec![Value::int(456)]),
Value::int(789),
])
);
@ -281,10 +271,11 @@ mod tests {
fn value_macro_object() {
assert_eq!(
graphql_value!({ "key": 123, "next": true }),
Value::object(vec![
("key", Value::int(123)),
("next", Value::boolean(true)),
].into_iter().collect())
Value::object(
vec![("key", Value::int(123)), ("next", Value::boolean(true))]
.into_iter()
.collect()
)
);
}
}

View file

@ -4,7 +4,6 @@ use quote::Tokens;
use util::*;
#[derive(Default, Debug)]
struct EnumAttrs {
name: Option<String>,
@ -14,7 +13,7 @@ struct EnumAttrs {
impl EnumAttrs {
fn from_input(input: &DeriveInput) -> EnumAttrs {
let mut res = EnumAttrs{
let mut res = EnumAttrs {
name: None,
description: None,
/// Flag to specify whether the calling crate is the "juniper" crate itself.
@ -38,8 +37,8 @@ impl EnumAttrs {
res.internal = true;
continue;
}
},
_ => {},
}
_ => {}
}
panic!(format!(
"Unknown attribute for #[derive(GraphQLEnum)]: {:?}",
@ -87,7 +86,6 @@ impl EnumVariantAttrs {
}
}
pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
let variants = match ast.body {
Body::Enum(ref var) => var,
@ -171,7 +169,9 @@ pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
Some(#name)
}
fn meta<'r>(_: &(), registry: &mut _juniper::Registry<'r>) -> _juniper::meta::MetaType<'r> {
fn meta<'r>(_: &(), registry: &mut _juniper::Registry<'r>)
-> _juniper::meta::MetaType<'r>
{
let meta = registry.build_enum_type::<#ident>(&(), &[
#(#values)*
]);
@ -179,7 +179,12 @@ pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
meta.into_meta()
}
fn resolve(&self, _: &(), _: Option<&[_juniper::Selection]>, _: &_juniper::Executor<Self::Context>) -> _juniper::Value {
fn resolve(
&self,
_: &(),
_: Option<&[_juniper::Selection]>,
_: &_juniper::Executor<Self::Context>
) -> _juniper::Value {
match self {
#(#resolves)*
}

View file

@ -4,7 +4,6 @@ use quote::Tokens;
use util::*;
#[derive(Default, Debug)]
struct ObjAttrs {
name: Option<String>,
@ -33,8 +32,8 @@ impl ObjAttrs {
res.internal = true;
continue;
}
},
_ => {},
}
_ => {}
}
panic!(format!(
"Unknown attribute for #[derive(GraphQLInputObject)]: {:?}",
@ -80,7 +79,7 @@ impl ObjFieldAttrs {
continue;
}
}
_ => {},
_ => {}
}
panic!(format!(
"Unknown attribute for #[derive(GraphQLInputObject)]: {:?}",
@ -144,7 +143,7 @@ pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens {
let default = {
if field_attrs.default {
Some(quote! { Default::default() } )
Some(quote! { Default::default() })
} else {
match field_attrs.default_expr {
Some(ref def) => match syn::parse_token_trees(def) {
@ -221,7 +220,10 @@ pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens {
Some(#name)
}
fn meta<'r>(_: &(), registry: &mut _juniper::Registry<'r>) -> _juniper::meta::MetaType<'r> {
fn meta<'r>(
_: &(),
registry: &mut _juniper::Registry<'r>
) -> _juniper::meta::MetaType<'r> {
let fields = &[
#(#meta_fields)*
];

View file

@ -135,7 +135,6 @@ pub fn impl_object(ast: &syn::DeriveInput) -> Tokens {
// Build from_input clause.
let resolver = quote!{
#name => executor.resolve_with_ctx(&(), &self.#field_ident),
};
@ -155,7 +154,10 @@ pub fn impl_object(ast: &syn::DeriveInput) -> Tokens {
#name.to_string()
}
fn meta<'r>(_: &(), registry: &mut ::juniper::Registry<'r>) -> ::juniper::meta::MetaType<'r> {
fn meta<'r>(
_: &(),
registry: &mut ::juniper::Registry<'r>
) -> ::juniper::meta::MetaType<'r> {
let fields = &[
#(#meta_fields)*
];
@ -164,8 +166,13 @@ pub fn impl_object(ast: &syn::DeriveInput) -> Tokens {
builder.into_meta()
}
fn resolve_field(&self, _: &(), field_name: &str, _: &::juniper::Arguments, executor: &::juniper::Executor<Self::Context>)
-> ::juniper::ExecutionResult
fn resolve_field(
&self,
_: &(),
field_name: &str,
_: &::juniper::Arguments,
executor: &::juniper::Executor<Self::Context>
) -> ::juniper::ExecutionResult
{
match field_name {

View file

@ -7,9 +7,9 @@
#![recursion_limit = "1024"]
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;
extern crate syn;
mod util;
mod derive_enum;

View file

@ -87,8 +87,7 @@ pub(crate) fn to_upper_snake_case(s: &str) -> String {
for c in s.chars() {
if c == '_' {
last_lower = false;
}
else if c.is_lowercase() {
} else if c.is_lowercase() {
last_lower = true;
} else if c.is_uppercase() {
if last_lower {

View file

@ -1,9 +1,9 @@
extern crate iron;
extern crate mount;
extern crate logger;
extern crate serde;
extern crate juniper;
extern crate juniper_iron;
extern crate logger;
extern crate mount;
extern crate serde;
use std::env;

View file

@ -101,13 +101,13 @@ supported.
*/
extern crate serde_json;
extern crate juniper;
extern crate urlencoded;
#[macro_use]
extern crate iron;
#[cfg(test)]
extern crate iron_test;
extern crate juniper;
extern crate serde_json;
extern crate urlencoded;
use iron::prelude::*;
use iron::middleware::Handler;
@ -151,14 +151,11 @@ pub struct GraphiQLHandler {
graphql_url: String,
}
fn get_single_value<T>(mut values: Vec<T>) -> IronResult<T> {
if values.len() == 1 {
Ok(values.remove(0))
} else {
Err(
GraphQLIronError::InvalidData("Duplicate URL query parameter").into(),
)
Err(GraphQLIronError::InvalidData("Duplicate URL query parameter").into())
}
}
@ -172,22 +169,22 @@ fn parse_url_param(params: Option<Vec<String>>) -> IronResult<Option<String>> {
fn parse_variable_param(params: Option<Vec<String>>) -> IronResult<Option<InputValue>> {
if let Some(values) = params {
Ok(serde_json::from_str::<InputValue>(
get_single_value(values)?.as_ref(),
).map(Some)
.map_err(GraphQLIronError::Serde)?)
Ok(
serde_json::from_str::<InputValue>(get_single_value(values)?.as_ref())
.map(Some)
.map_err(GraphQLIronError::Serde)?,
)
} else {
Ok(None)
}
}
impl<'a, CtxFactory, Query, Mutation, CtxT> GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT>
where
CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
CtxT: 'static,
Query: GraphQLType<Context = CtxT, TypeInfo=()> + Send + Sync + 'static,
Mutation: GraphQLType<Context = CtxT, TypeInfo=()> + Send + Sync + 'static,
Query: GraphQLType<Context = CtxT, TypeInfo = ()> + Send + Sync + 'static,
Mutation: GraphQLType<Context = CtxT, TypeInfo = ()> + Send + Sync + 'static,
{
/// Build a new GraphQL handler
///
@ -202,7 +199,6 @@ where
}
}
fn handle_get(&self, req: &mut Request) -> IronResult<http::GraphQLRequest> {
let url_query_string = req.get_mut::<UrlEncodedQuery>()
.map_err(|e| GraphQLIronError::Url(e))?;
@ -223,9 +219,10 @@ where
let mut request_payload = String::new();
itry!(req.body.read_to_string(&mut request_payload));
Ok(serde_json::from_str::<http::GraphQLRequest>(
request_payload.as_str(),
).map_err(|err| GraphQLIronError::Serde(err))?)
Ok(
serde_json::from_str::<http::GraphQLRequest>(request_payload.as_str())
.map_err(|err| GraphQLIronError::Serde(err))?,
)
}
fn execute(&self, context: &CtxT, request: http::GraphQLRequest) -> IronResult<Response> {
@ -258,8 +255,8 @@ impl<'a, CtxFactory, Query, Mutation, CtxT> Handler
where
CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
CtxT: 'static,
Query: GraphQLType<Context = CtxT, TypeInfo=()> + Send + Sync + 'static,
Mutation: GraphQLType<Context = CtxT, TypeInfo=()> + Send + Sync + 'static,
Query: GraphQLType<Context = CtxT, TypeInfo = ()> + Send + Sync + 'static,
Mutation: GraphQLType<Context = CtxT, TypeInfo = ()> + Send + Sync + 'static,
'a: 'static,
{
fn handle(&self, mut req: &mut Request) -> IronResult<Response> {

View file

@ -1,9 +1,9 @@
#![feature(plugin)]
#![plugin(rocket_codegen)]
extern crate rocket;
extern crate juniper;
extern crate juniper_rocket;
extern crate rocket;
use rocket::response::content;
use rocket::State;

View file

@ -40,8 +40,8 @@ Check the LICENSE file for details.
#![plugin(rocket_codegen)]
extern crate juniper;
extern crate serde_json;
extern crate rocket;
extern crate serde_json;
use std::io::{Cursor, Read};
use std::error::Error;
@ -123,9 +123,8 @@ impl<'f> FromForm<'f> for GraphQLRequest {
}
"operation_name" => {
if operation_name.is_some() {
return Err(
"Operation name parameter must not occur more than once".to_owned(),
);
return Err("Operation name parameter must not occur more than once"
.to_owned());
} else {
match value.url_decode() {
Ok(v) => operation_name = Some(v),
@ -135,20 +134,15 @@ impl<'f> FromForm<'f> for GraphQLRequest {
}
"variables" => {
if variables.is_some() {
return Err(
"Variables parameter must not occur more than once".to_owned(),
);
return Err("Variables parameter must not occur more than once".to_owned());
} else {
let decoded;
match value.url_decode() {
Ok(v) => decoded = v,
Err(e) => return Err(e.description().to_string()),
}
variables = Some(serde_json::from_str::<InputValue>(&decoded).map_err(
|err| {
err.description().to_owned()
},
)?);
variables = Some(serde_json::from_str::<InputValue>(&decoded)
.map_err(|err| err.description().to_owned())?);
}
}
_ => {
@ -160,9 +154,11 @@ impl<'f> FromForm<'f> for GraphQLRequest {
}
if let Some(query) = query {
Ok(GraphQLRequest(
http::GraphQLRequest::new(query, operation_name, variables),
))
Ok(GraphQLRequest(http::GraphQLRequest::new(
query,
operation_name,
variables,
)))
} else {
Err("Query parameter missing".to_owned())
}
@ -193,13 +189,11 @@ impl<'r> Responder<'r> for GraphQLResponse {
fn respond_to(self, _: &Request) -> Result<Response<'r>, Status> {
let GraphQLResponse(status, body) = self;
Ok(
Response::build()
.header(ContentType::new("application", "json"))
.status(status)
.sized_body(Cursor::new(body))
.finalize(),
)
Ok(Response::build()
.header(ContentType::new("application", "json"))
.status(status)
.sized_body(Cursor::new(body))
.finalize())
}
}
@ -208,7 +202,7 @@ mod fromform_tests {
use super::*;
use std::str;
use juniper::InputValue;
use rocket::request::{FromForm, FormItems};
use rocket::request::{FormItems, FromForm};
fn check_error(input: &str, error: &str, strict: bool) {
let mut items = FormItems::from(input);
@ -224,16 +218,16 @@ mod fromform_tests {
#[test]
fn test_no_query() {
check_error("operation_name=foo&variables={}", "Query parameter missing", false);
check_error(
"operation_name=foo&variables={}",
"Query parameter missing",
false,
);
}
#[test]
fn test_strict() {
check_error(
"query=test&foo=bar",
"Prohibited extra field \'foo\'",
true,
);
check_error("query=test&foo=bar", "Prohibited extra field \'foo\'", true);
}
#[test]

View file

@ -9,8 +9,7 @@ use juniper::{self, FromInputValue, GraphQLType, InputValue, ToInputValue};
enum SomeEnum {
Regular,
#[graphql(name = "full", description = "field descr", deprecated = "depr")]
Full,
#[graphql(name = "full", description = "field descr", deprecated = "depr")] Full,
}
#[test]
@ -26,14 +25,20 @@ fn test_derived_enum() {
assert_eq!(meta.description(), Some(&"enum descr".to_string()));
// Test Regular variant.
assert_eq!(SomeEnum::Regular.to_input_value(), InputValue::String("REGULAR".into()));
assert_eq!(
SomeEnum::Regular.to_input_value(),
InputValue::String("REGULAR".into())
);
assert_eq!(
FromInputValue::from_input_value(&InputValue::String("REGULAR".into())),
Some(SomeEnum::Regular)
);
// Test FULL variant.
assert_eq!(SomeEnum::Full.to_input_value(), InputValue::String("full".into()));
assert_eq!(
SomeEnum::Full.to_input_value(),
InputValue::String("full".into())
);
assert_eq!(
FromInputValue::from_input_value(&InputValue::String("full".into())),
Some(SomeEnum::Full)

View file

@ -8,11 +8,9 @@ use juniper::{self, FromInputValue, GraphQLType, InputValue};
#[graphql(name = "MyInput", description = "input descr")]
struct Input {
regular_field: String,
#[graphql(name = "haha", default = "33", description = "haha descr")]
c: i32,
#[graphql(name = "haha", default = "33", description = "haha descr")] c: i32,
#[graphql(default)]
other: Option<bool>,
#[graphql(default)] other: Option<bool>,
}
#[test]
@ -32,11 +30,14 @@ fn test_derived_input_object() {
})).unwrap();
let output_no_defaults: Input = FromInputValue::from_input_value(&input_no_defaults).unwrap();
assert_eq!(output_no_defaults, Input{
regular_field: "a".into(),
c: 33,
other: None,
});
assert_eq!(
output_no_defaults,
Input {
regular_field: "a".into(),
c: 33,
other: None,
}
);
// Test with all values supplied.
@ -47,9 +48,12 @@ fn test_derived_input_object() {
})).unwrap();
let output: Input = FromInputValue::from_input_value(&input).unwrap();
assert_eq!(output, Input{
regular_field: "a".into(),
c: 55,
other: Some(true),
});
assert_eq!(
output,
Input {
regular_field: "a".into(),
c: 55,
other: Some(true),
}
);
}

View file

@ -8,8 +8,7 @@ use juniper::{self, execute, EmptyMutation, GraphQLType, RootNode, Value, Variab
#[graphql(name = "MyObj", description = "obj descr")]
struct Obj {
regular_field: bool,
#[graphql(name = "renamedField", description = "descr", deprecation = "field descr")]
c: i32,
#[graphql(name = "renamedField", description = "descr", deprecation = "field descr")] c: i32,
}
#[derive(GraphQLObject, Debug, PartialEq)]
@ -59,14 +58,26 @@ fn test_derived_object() {
let schema = RootNode::new(Query, EmptyMutation::<()>::new());
assert_eq!(
execute(doc, None, &schema, &Variables::new(), &()),
Ok((Value::object(vec![
("obj", Value::object(vec![
("regularField", Value::boolean(true)),
("renamedField", Value::int(22)),
].into_iter().collect())),
].into_iter().collect()),
vec![])));
execute(doc, None, &schema, &Variables::new(), &()),
Ok((
Value::object(
vec![
(
"obj",
Value::object(
vec![
("regularField", Value::boolean(true)),
("renamedField", Value::int(22)),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
),
vec![]
))
);
}
#[test]
@ -85,13 +96,31 @@ fn test_derived_object_nested() {
assert_eq!(
execute(doc, None, &schema, &Variables::new(), &()),
Ok((Value::object(vec![
("nested", Value::object(vec![
("obj", Value::object(vec![
("regularField", Value::boolean(false)),
("renamedField", Value::int(333)),
].into_iter().collect())
)].into_iter().collect())),
].into_iter().collect()),
vec![])));
Ok((
Value::object(
vec![
(
"nested",
Value::object(
vec![
(
"obj",
Value::object(
vec![
("regularField", Value::boolean(false)),
("renamedField", Value::int(333)),
].into_iter()
.collect(),
),
),
].into_iter()
.collect(),
),
),
].into_iter()
.collect()
),
vec![]
))
);
}