Merge pull request #14 from zaeleus/variables-type-alias

Add type alias for query variables
This commit is contained in:
Magnus Hallin 2017-01-19 09:28:52 -08:00 committed by GitHub
commit 907d78d41b
17 changed files with 71 additions and 63 deletions

View file

@ -3,9 +3,7 @@ extern crate juniper;
use bencher::Bencher;
use std::collections::{HashMap};
use juniper::{execute, RootNode, EmptyMutation};
use juniper::{execute, RootNode, EmptyMutation, Variables};
use juniper::tests::model::Database;
fn query_type_name(b: &mut Bencher) {
@ -21,7 +19,7 @@ fn query_type_name(b: &mut Bencher) {
}
}"#;
b.iter(|| execute(doc, None, &schema, &HashMap::new(), &database));
b.iter(|| execute(doc, None, &schema, &Variables::new(), &database));
}
fn introspection_query(b: &mut Bencher) {
@ -122,7 +120,7 @@ fn introspection_query(b: &mut Bencher) {
}
"#;
b.iter(|| execute(doc, None, &schema, &HashMap::new(), &database));
b.iter(|| execute(doc, None, &schema, &Variables::new(), &database));
}
benchmark_group!(queries, query_type_name, introspection_query);

View file

@ -4,6 +4,7 @@ use std::hash::Hash;
use std::vec;
use std::slice;
use executor::Variables;
use parser::Spanning;
/// A type literal in the syntax tree
@ -265,7 +266,7 @@ impl InputValue {
}
/// Resolve all variables to their values.
pub fn into_const(self, vars: &HashMap<String, InputValue>) -> InputValue {
pub fn into_const(self, vars: &Variables) -> InputValue {
match self {
InputValue::Variable(v) => vars.get(&v)
.map_or_else(InputValue::null, Clone::clone),

View file

@ -36,7 +36,7 @@ pub enum FieldPath<'a> {
/// of the current field stack, context, variables, and errors.
pub struct Executor<'a, CtxT> where CtxT: 'a {
fragments: &'a HashMap<&'a str, &'a Fragment<'a>>,
variables: &'a HashMap<String, InputValue>,
variables: &'a Variables,
current_selection_set: Option<&'a [Selection<'a>]>,
schema: &'a SchemaType<'a>,
context: &'a CtxT,
@ -61,6 +61,9 @@ pub type FieldResult<T> = Result<T, String>;
/// The result of resolving an unspecified field
pub type ExecutionResult = Result<Value, String>;
/// The map of variables used for substitution during query execution
pub type Variables = HashMap<String, InputValue>;
#[doc(hidden)]
pub trait IntoResolvable<'a, T: GraphQLType, C>: Sized {
#[doc(hidden)]
@ -221,7 +224,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
}
#[doc(hidden)]
pub fn variables(&self) -> &'a HashMap<String, InputValue> {
pub fn variables(&self) -> &'a Variables {
self.variables
}
@ -294,7 +297,7 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
document: Document,
operation_name: Option<&str>,
root_node: &RootNode<QueryT, MutationT>,
variables: &HashMap<String, InputValue>,
variables: &Variables,
context: &CtxT
)
-> Result<(Value, Vec<ExecutionError>), GraphQLError<'a>>

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use value::Value;
use ast::InputValue;
use executor::Variables;
use schema::model::RootNode;
use types::scalars::EmptyMutation;
@ -17,7 +18,7 @@ graphql_object!(TestType: () |&self| {
}
});
fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
fn run_variable_query<F>(query: &str, vars: Variables, f: F)
where F: Fn(&HashMap<String, Value>) -> ()
{
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
@ -37,7 +38,7 @@ fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
fn run_query<F>(query: &str, f: F)
where F: Fn(&HashMap<String, Value>) -> ()
{
run_variable_query(query, HashMap::new(), f);
run_variable_query(query, Variables::new(), f);
}
#[test]

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use value::Value;
use ast::InputValue;
use executor::Variables;
use schema::model::RootNode;
use ::GraphQLError::ValidationError;
use validation::RuleError;
@ -28,7 +29,7 @@ graphql_object!(TestType: () |&self| {
}
});
fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
fn run_variable_query<F>(query: &str, vars: Variables, f: F)
where F: Fn(&HashMap<String, Value>) -> ()
{
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
@ -48,7 +49,7 @@ fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
fn run_query<F>(query: &str, f: F)
where F: Fn(&HashMap<String, Value>) -> ()
{
run_variable_query(query, HashMap::new(), f);
run_variable_query(query, Variables::new(), f);
}
#[test]

View file

@ -1,5 +1,4 @@
use std::collections::HashMap;
use executor::Variables;
use value::Value;
use schema::model::RootNode;
use types::scalars::EmptyMutation;
@ -70,7 +69,7 @@ fn test_execution() {
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);
@ -107,7 +106,7 @@ fn enum_introspection() {
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);
@ -185,7 +184,7 @@ fn interface_introspection() {
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);
@ -286,7 +285,7 @@ fn object_introspection() {
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);
@ -398,7 +397,7 @@ fn scalar_introspection() {
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use value::Value;
use ast::InputValue;
use executor::Variables;
use schema::model::RootNode;
use ::GraphQLError::ValidationError;
use validation::RuleError;
@ -86,7 +87,7 @@ graphql_object!(TestType: () |&self| {
}
});
fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
fn run_variable_query<F>(query: &str, vars: Variables, f: F)
where F: Fn(&HashMap<String, Value>) -> ()
{
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
@ -106,7 +107,7 @@ fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
fn run_query<F>(query: &str, f: F)
where F: Fn(&HashMap<String, Value>) -> ()
{
run_variable_query(query, HashMap::new(), f);
run_variable_query(query, Variables::new(), f);
}
#[test]

View file

@ -6,11 +6,11 @@ use iron::mime::Mime;
use iron::status;
use iron::method;
use std::collections::{HashMap, BTreeMap};
use std::collections::BTreeMap;
use rustc_serialize::json::{ToJson, Json};
use ::{InputValue, GraphQLType, RootNode, execute};
use ::{InputValue, GraphQLType, RootNode, Variables, execute};
/// Handler that executes GraphQL queries in the given schema
///
@ -62,7 +62,7 @@ impl<'a, CtxFactory, Query, Mutation, CtxT>
let url = req.url.clone().into_generic_url();
let mut query = None;
let variables = HashMap::new();
let variables = Variables::new();
for (k, v) in url.query_pairs() {
if k == "query" {
@ -84,17 +84,16 @@ impl<'a, CtxFactory, Query, Mutation, CtxT>
};
let mut query = None;
let mut variables = HashMap::new();
let mut variables = Variables::new();
for (k, v) in json_obj.into_iter() {
if k == "query" {
query = v.as_string().map(|s| s.to_owned());
}
else if k == "variables" {
variables = match InputValue::from_json(v).to_object_value() {
Some(o) => o.into_iter().map(|(k, v)| (k.to_owned(), v.clone())).collect(),
_ => HashMap::new(),
};
variables = InputValue::from_json(v).to_object_value()
.map(|o| o.into_iter().map(|(k, v)| (k.to_owned(), v.clone())).collect())
.unwrap_or_default();
}
}
@ -103,7 +102,7 @@ impl<'a, CtxFactory, Query, Mutation, CtxT>
self.execute(req, &query, &variables)
}
fn execute(&self, req: &mut Request, query: &str, variables: &HashMap<String, InputValue>) -> IronResult<Response> {
fn execute(&self, req: &mut Request, query: &str, variables: &Variables) -> IronResult<Response> {
let context = (self.context_factory)(req);
let result = execute(query, None, &self.root_node, variables, &context);

View file

@ -209,8 +209,6 @@ mod integrations;
#[cfg(test)] mod executor_tests;
use std::collections::HashMap;
use parser::{parse_document_source, ParseError, Spanning};
use validation::{ValidatorContext, visit_all_rules, validate_input_values};
use executor::execute_validated_query;
@ -219,8 +217,9 @@ pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection};
pub use value::Value;
pub use types::base::{Arguments, GraphQLType, TypeKind};
pub use executor::{
Context, FromContext,
Executor, Registry, ExecutionResult, ExecutionError, FieldResult, IntoResolvable,
Executor, ExecutionError, Registry,
Context, FromContext, IntoResolvable,
FieldResult, ExecutionResult, Variables,
};
pub use validation::RuleError;
pub use types::scalars::{EmptyMutation, ID};
@ -247,7 +246,7 @@ pub fn execute<'a, CtxT, QueryT, MutationT>(
document_source: &'a str,
operation_name: Option<&str>,
root_node: &RootNode<QueryT, MutationT>,
variables: &HashMap<String, InputValue>,
variables: &Variables,
context: &CtxT,
)
-> Result<(Value, Vec<ExecutionError>), GraphQLError<'a>>

View file

@ -1,5 +1,6 @@
use std::collections::HashMap;
use executor::Variables;
use value::Value;
use schema::model::RootNode;
use types::scalars::EmptyMutation;
@ -90,7 +91,7 @@ fn run_args_info_query<F>(field_name: &str, f: F)
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);

View file

@ -1,5 +1,6 @@
use std::collections::HashMap;
use executor::Variables;
use value::Value;
use schema::model::RootNode;
use types::scalars::EmptyMutation;
@ -70,7 +71,7 @@ graphql_object!(Root: () |&self| {
fn run_type_info_query<F>(doc: &str, f: F) where F: Fn((&HashMap<String, Value>, &Vec<Value>)) -> () {
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);

View file

@ -1,6 +1,7 @@
use std::collections::HashMap;
use ast::{InputValue, FromInputValue};
use executor::Variables;
use value::Value;
use schema::model::RootNode;
use types::scalars::EmptyMutation;
@ -97,7 +98,7 @@ graphql_object!(Root: () |&self| {
fn run_type_info_query<F>(doc: &str, f: F) where F: Fn(&HashMap<String, Value>, &Vec<Value>) -> () {
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);

View file

@ -1,5 +1,6 @@
use std::collections::HashMap;
use executor::Variables;
use value::Value;
use schema::model::RootNode;
use types::scalars::EmptyMutation;
@ -72,7 +73,7 @@ graphql_object!(Root: () |&self| {
fn run_type_info_query<F>(doc: &str, f: F) where F: Fn(&HashMap<String, Value>) -> () {
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);

View file

@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;
use executor::Variables;
use value::Value;
use schema::model::RootNode;
use tests::model::Database;
@ -19,7 +20,7 @@ fn test_query_type_name() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("__schema", Value::object(vec![
("queryType", Value::object(vec![
@ -42,7 +43,7 @@ fn test_specific_type_name() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("__type", Value::object(vec![
("name", Value::string("Droid")),
@ -65,7 +66,7 @@ fn test_specific_object_type_name_and_kind() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("__type", Value::object(vec![
("name", Value::string("Droid")),
@ -89,7 +90,7 @@ fn test_specific_interface_type_name_and_kind() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("__type", Value::object(vec![
("name", Value::string("Character")),
@ -113,7 +114,7 @@ fn test_documentation() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((
Value::object(vec![
("__type", Value::object(vec![
@ -138,7 +139,7 @@ fn test_possible_types() {
let database = Database::new();
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
let result = ::execute(doc, None, &schema, &HashMap::new(), &database);
let result = ::execute(doc, None, &schema, &Variables::new(), &database);
println!("Result: {:#?}", result);

View file

@ -1,6 +1,5 @@
use std::collections::HashMap;
use ast::InputValue;
use executor::Variables;
use value::Value;
use schema::model::RootNode;
use types::scalars::EmptyMutation;
@ -18,7 +17,7 @@ fn test_hero_name() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("hero", Value::object(vec![
("name", Value::string("R2-D2")),
@ -43,7 +42,7 @@ fn test_hero_name_and_friends() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("hero", Value::object(vec![
("id", Value::string("2001")),
@ -84,7 +83,7 @@ fn test_hero_name_and_friends_and_friends_of_friends() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("hero", Value::object(vec![
("id", Value::string("2001")),
@ -166,7 +165,7 @@ fn test_query_name() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("human", Value::object(vec![
("name", Value::string("Luke Skywalker")),
@ -182,7 +181,7 @@ fn test_query_alias_single() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("luke", Value::object(vec![
("name", Value::string("Luke Skywalker")),
@ -202,7 +201,7 @@ fn test_query_alias_multiple() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("luke", Value::object(vec![
("name", Value::string("Luke Skywalker")),
@ -230,7 +229,7 @@ fn test_query_alias_multiple_with_fragment() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("luke", Value::object(vec![
("name", Value::string("Luke Skywalker")),
@ -289,7 +288,7 @@ fn test_query_friends_names() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("human", Value::object(vec![
("friends", Value::list(vec![
@ -329,7 +328,7 @@ fn test_query_inline_fragments_droid() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("hero", Value::object(vec![
("__typename", Value::string("Droid")),
@ -354,7 +353,7 @@ fn test_query_inline_fragments_human() {
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
assert_eq!(
::execute(doc, None, &schema, &HashMap::new(), &database),
::execute(doc, None, &schema, &Variables::new(), &database),
Ok((Value::object(vec![
("hero", Value::object(vec![
("__typename", Value::string("Human")),

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::collections::hash_map::Entry;
use ast::{InputValue, Selection, Directive, FromInputValue};
use executor::Variables;
use value::Value;
use schema::meta::{Argument, MetaType};
@ -390,7 +391,7 @@ fn resolve_selection_set_into<T, CtxT>(
}
}
fn is_excluded(directives: &Option<Vec<Spanning<Directive>>>, vars: &HashMap<String, InputValue>) -> bool {
fn is_excluded(directives: &Option<Vec<Spanning<Directive>>>, vars: &Variables) -> bool {
if let Some(ref directives) = *directives {
for &Spanning { item: ref directive, .. } in directives {
let condition: bool = directive.arguments.iter()

View file

@ -1,8 +1,9 @@
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;
use std::fmt;
use parser::SourcePosition;
use ast::{InputValue, Document, Definition, VariableDefinitions};
use executor::Variables;
use validation::RuleError;
use schema::model::{SchemaType, TypeType};
use schema::meta::{MetaType, ScalarMeta, InputObjectMeta, EnumMeta};
@ -15,7 +16,7 @@ enum Path<'a> {
}
pub fn validate_input_values(
values: &HashMap<String, InputValue>,
values: &Variables,
document: &Document,
schema: &SchemaType,
)
@ -36,7 +37,7 @@ pub fn validate_input_values(
}
fn validate_var_defs(
values: &HashMap<String, InputValue>,
values: &Variables,
var_defs: &VariableDefinitions,
schema: &SchemaType,
errors: &mut Vec<RuleError>,