Use borrowed string references in all AST nodes

This commit is contained in:
Magnus Hallin 2016-12-28 18:54:09 +01:00
parent f066fca1f4
commit 853c92a0b7
25 changed files with 121 additions and 127 deletions

View file

@ -55,35 +55,35 @@ pub struct VariableDefinition<'a> {
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct Arguments { pub struct Arguments<'a> {
pub items: Vec<(Spanning<String>, Spanning<InputValue>)>, pub items: Vec<(Spanning<&'a str>, Spanning<InputValue>)>,
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct VariableDefinitions<'a> { pub struct VariableDefinitions<'a> {
pub items: Vec<(Spanning<String>, VariableDefinition<'a>)>, pub items: Vec<(Spanning<&'a str>, VariableDefinition<'a>)>,
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct Field { pub struct Field<'a> {
pub alias: Option<Spanning<String>>, pub alias: Option<Spanning<&'a str>>,
pub name: Spanning<String>, pub name: Spanning<&'a str>,
pub arguments: Option<Spanning<Arguments>>, pub arguments: Option<Spanning<Arguments<'a>>>,
pub directives: Option<Vec<Spanning<Directive>>>, pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub selection_set: Option<Vec<Selection>>, pub selection_set: Option<Vec<Selection<'a>>>,
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct FragmentSpread { pub struct FragmentSpread<'a> {
pub name: Spanning<String>, pub name: Spanning<&'a str>,
pub directives: Option<Vec<Spanning<Directive>>>, pub directives: Option<Vec<Spanning<Directive<'a>>>>,
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct InlineFragment { pub struct InlineFragment<'a> {
pub type_condition: Option<Spanning<String>>, pub type_condition: Option<Spanning<&'a str>>,
pub directives: Option<Vec<Spanning<Directive>>>, pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub selection_set: Vec<Selection>, pub selection_set: Vec<Selection<'a>>,
} }
/// Entry in a GraphQL selection set /// Entry in a GraphQL selection set
@ -103,16 +103,16 @@ pub struct InlineFragment {
/// ``` /// ```
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum Selection { pub enum Selection<'a> {
Field(Spanning<Field>), Field(Spanning<Field<'a>>),
FragmentSpread(Spanning<FragmentSpread>), FragmentSpread(Spanning<FragmentSpread<'a>>),
InlineFragment(Spanning<InlineFragment>), InlineFragment(Spanning<InlineFragment<'a>>),
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct Directive { pub struct Directive<'a> {
pub name: Spanning<String>, pub name: Spanning<&'a str>,
pub arguments: Option<Spanning<Arguments>>, pub arguments: Option<Spanning<Arguments<'a>>>,
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
@ -124,24 +124,24 @@ pub enum OperationType {
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct Operation<'a> { pub struct Operation<'a> {
pub operation_type: OperationType, pub operation_type: OperationType,
pub name: Option<Spanning<String>>, pub name: Option<Spanning<&'a str>>,
pub variable_definitions: Option<Spanning<VariableDefinitions<'a>>>, pub variable_definitions: Option<Spanning<VariableDefinitions<'a>>>,
pub directives: Option<Vec<Spanning<Directive>>>, pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub selection_set: Vec<Selection>, pub selection_set: Vec<Selection<'a>>,
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct Fragment { pub struct Fragment<'a> {
pub name: Spanning<String>, pub name: Spanning<&'a str>,
pub type_condition: Spanning<String>, pub type_condition: Spanning<&'a str>,
pub directives: Option<Vec<Spanning<Directive>>>, pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub selection_set: Vec<Selection>, pub selection_set: Vec<Selection<'a>>,
} }
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum Definition<'a> { pub enum Definition<'a> {
Operation(Spanning<Operation<'a>>), Operation(Spanning<Operation<'a>>),
Fragment(Spanning<Fragment>), Fragment(Spanning<Fragment<'a>>),
} }
pub type Document<'a> = Vec<Definition<'a>>; pub type Document<'a> = Vec<Definition<'a>>;
@ -417,23 +417,19 @@ impl ToJson for InputValue {
} }
} }
impl Arguments { impl<'a> Arguments<'a> {
pub fn into_iter(self) -> vec::IntoIter<(Spanning<String>, Spanning<InputValue>)> { pub fn into_iter(self) -> vec::IntoIter<(Spanning<&'a str>, Spanning<InputValue>)> {
self.items.into_iter() self.items.into_iter()
} }
pub fn iter(&self) -> slice::Iter<(Spanning<String>, Spanning<InputValue>)> { pub fn iter(&self) -> slice::Iter<(Spanning<&'a str>, Spanning<InputValue>)> {
self.items.iter() self.items.iter()
} }
pub fn iter_mut(&mut self) -> slice::IterMut<(Spanning<String>, Spanning<InputValue>)> { pub fn iter_mut(&mut self) -> slice::IterMut<(Spanning<&'a str>, Spanning<InputValue>)> {
self.items.iter_mut() self.items.iter_mut()
} }
pub fn drain<'a>(&'a mut self) -> vec::Drain<'a, (Spanning<String>, Spanning<InputValue>)> {
self.items.drain(..)
}
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.items.len() self.items.len()
} }
@ -448,7 +444,7 @@ impl Arguments {
} }
impl<'a> VariableDefinitions<'a> { impl<'a> VariableDefinitions<'a> {
pub fn iter(&self) -> slice::Iter<(Spanning<String>, VariableDefinition)> { pub fn iter(&self) -> slice::Iter<(Spanning<&'a str>, VariableDefinition)> {
self.items.iter() self.items.iter()
} }
} }

View file

@ -35,9 +35,9 @@ pub enum FieldPath<'a> {
/// The executor helps drive the query execution in a schema. It keeps track /// The executor helps drive the query execution in a schema. It keeps track
/// of the current field stack, context, variables, and errors. /// of the current field stack, context, variables, and errors.
pub struct Executor<'a, CtxT> where CtxT: 'a { pub struct Executor<'a, CtxT> where CtxT: 'a {
fragments: &'a HashMap<&'a str, &'a Fragment>, fragments: &'a HashMap<&'a str, &'a Fragment<'a>>,
variables: &'a HashMap<String, InputValue>, variables: &'a HashMap<String, InputValue>,
current_selection_set: Option<&'a [Selection]>, current_selection_set: Option<&'a [Selection<'a>]>,
schema: &'a SchemaType<'a>, schema: &'a SchemaType<'a>,
context: &'a CtxT, context: &'a CtxT,
errors: &'a RwLock<Vec<ExecutionError>>, errors: &'a RwLock<Vec<ExecutionError>>,
@ -332,7 +332,7 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
{ {
let executor = Executor { let executor = Executor {
fragments: &fragments.iter().map(|f| (f.item.name.item.as_str(), &f.item)).collect(), fragments: &fragments.iter().map(|f| (f.item.name.item, &f.item)).collect(),
variables: variables, variables: variables,
current_selection_set: Some(&op.item.selection_set[..]), current_selection_set: Some(&op.item.selection_set[..]),
schema: &root_node.schema, schema: &root_node.schema,

View file

@ -54,7 +54,7 @@ fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Op
let start_pos = parser.peek().start.clone(); let start_pos = parser.peek().start.clone();
let operation_type = try!(parse_operation_type(parser)); let operation_type = try!(parse_operation_type(parser));
let name = match parser.peek().item { let name = match parser.peek().item {
Token::Name(_) => Some(try!(parser.expect_name()).map(|s| s.to_owned())), Token::Name(_) => Some(try!(parser.expect_name())),
_ => None _ => None
}; };
let variable_definitions = try!(parse_variable_definitions(parser)); let variable_definitions = try!(parse_variable_definitions(parser));
@ -74,7 +74,7 @@ fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Op
} }
} }
fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fragment> { fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fragment<'a>> {
let Spanning { start: start_pos, .. } = try!(parser.expect(&Token::Name("fragment"))); let Spanning { start: start_pos, .. } = try!(parser.expect(&Token::Name("fragment")));
let name = match parser.expect_name() { let name = match parser.expect_name() {
Ok(n) => if n.item == "on" { Ok(n) => if n.item == "on" {
@ -95,14 +95,14 @@ fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fra
&start_pos, &start_pos,
&selection_set.end, &selection_set.end,
Fragment { Fragment {
name: name.map(|s| s.to_owned()), name: name,
type_condition: type_cond.map(|s| s.to_owned()), type_condition: type_cond,
directives: directives.map(|s| s.item), directives: directives.map(|s| s.item),
selection_set: selection_set.item, selection_set: selection_set.item,
})) }))
} }
fn parse_optional_selection_set<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Vec<Selection>> { fn parse_optional_selection_set<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Vec<Selection<'a>>> {
if parser.peek().item == Token::CurlyOpen { if parser.peek().item == Token::CurlyOpen {
Ok(Some(try!(parse_selection_set(parser)))) Ok(Some(try!(parse_selection_set(parser))))
} }
@ -111,21 +111,21 @@ fn parse_optional_selection_set<'a>(parser: &mut Parser<'a>) -> OptionParseResul
} }
} }
fn parse_selection_set<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Vec<Selection>> { fn parse_selection_set<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Vec<Selection<'a>>> {
parser.unlocated_delimited_nonempty_list( parser.unlocated_delimited_nonempty_list(
&Token::CurlyOpen, &Token::CurlyOpen,
parse_selection, parse_selection,
&Token::CurlyClose) &Token::CurlyClose)
} }
fn parse_selection<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selection> { fn parse_selection<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selection<'a>> {
match parser.peek().item { match parser.peek().item {
Token::Ellipsis => parse_fragment(parser), Token::Ellipsis => parse_fragment(parser),
_ => parse_field(parser).map(Selection::Field), _ => parse_field(parser).map(Selection::Field),
} }
} }
fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selection> { fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selection<'a>> {
let Spanning { start: ref start_pos, .. } = try!(parser.expect(&Token::Ellipsis)); let Spanning { start: ref start_pos, .. } = try!(parser.expect(&Token::Ellipsis));
match parser.peek().item { match parser.peek().item {
@ -140,7 +140,7 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
&start_pos.clone(), &start_pos.clone(),
&selection_set.end, &selection_set.end,
InlineFragment { InlineFragment {
type_condition: Some(name.map(|s| s.to_owned())), type_condition: Some(name),
directives: directives.map(|s| s.item), directives: directives.map(|s| s.item),
selection_set: selection_set.item, selection_set: selection_set.item,
}))) })))
@ -167,7 +167,7 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
&start_pos.clone(), &start_pos.clone(),
&directives.as_ref().map_or(&frag_name.end, |s| &s.end).clone(), &directives.as_ref().map_or(&frag_name.end, |s| &s.end).clone(),
FragmentSpread { FragmentSpread {
name: frag_name.map(|s| s.to_owned()), name: frag_name,
directives: directives.map(|s| s.item), directives: directives.map(|s| s.item),
}))) })))
}, },
@ -189,11 +189,11 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
} }
} }
fn parse_field<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Field> { fn parse_field<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Field<'a>> {
let mut alias = Some(try!(parser.expect_name()).map(|s| s.to_owned())); let mut alias = Some(try!(parser.expect_name()));
let name = if try!(parser.skip(&Token::Colon)).is_some() { let name = if try!(parser.skip(&Token::Colon)).is_some() {
try!(parser.expect_name()).map(|s| s.to_owned()) try!(parser.expect_name())
} }
else { else {
alias.take().unwrap() alias.take().unwrap()
@ -212,14 +212,14 @@ fn parse_field<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Field> {
.clone(), .clone(),
Field { Field {
alias: alias, alias: alias,
name: name.map(|s| s.to_owned()), name: name,
arguments: arguments, arguments: arguments,
directives: directives.map(|s| s.item), directives: directives.map(|s| s.item),
selection_set: selection_set.map(|s| s.item), selection_set: selection_set.map(|s| s.item),
})) }))
} }
fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Arguments> { fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Arguments<'a>> {
if parser.peek().item != Token::ParenOpen { if parser.peek().item != Token::ParenOpen {
Ok(None) Ok(None)
} else { } else {
@ -231,7 +231,7 @@ fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Argumen
} }
} }
fn parse_argument<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Spanning<String>, Spanning<InputValue>)> { fn parse_argument<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Spanning<&'a str>, Spanning<InputValue>)> {
let name = try!(parser.expect_name()); let name = try!(parser.expect_name());
try!(parser.expect(&Token::Colon)); try!(parser.expect(&Token::Colon));
let value = try!(parse_value_literal(parser, false)); let value = try!(parse_value_literal(parser, false));
@ -239,7 +239,7 @@ fn parse_argument<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Spanning<Stri
Ok(Spanning::start_end( Ok(Spanning::start_end(
&name.start.clone(), &name.start.clone(),
&value.end.clone(), &value.end.clone(),
(name.map(|s| s.to_owned()), value))) (name, value)))
} }
fn parse_operation_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, OperationType> { fn parse_operation_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, OperationType> {
@ -263,7 +263,7 @@ fn parse_variable_definitions<'a>(parser: &mut Parser<'a>) -> OptionParseResult<
} }
} }
fn parse_variable_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Spanning<String>, VariableDefinition<'a>)> { fn parse_variable_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Spanning<&'a str>, VariableDefinition<'a>)> {
let Spanning { start: start_pos, .. } = try!(parser.expect(&Token::Dollar)); let Spanning { start: start_pos, .. } = try!(parser.expect(&Token::Dollar));
let var_name = try!(parser.expect_name()); let var_name = try!(parser.expect_name());
try!(parser.expect(&Token::Colon)); try!(parser.expect(&Token::Colon));
@ -283,7 +283,7 @@ fn parse_variable_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Sp
Spanning::start_end( Spanning::start_end(
&start_pos, &start_pos,
&var_name.end, &var_name.end,
var_name.item.to_owned(), var_name.item,
), ),
VariableDefinition { VariableDefinition {
var_type: var_type, var_type: var_type,
@ -292,7 +292,7 @@ fn parse_variable_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Sp
))) )))
} }
fn parse_directives<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Vec<Spanning<Directive>>> { fn parse_directives<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Vec<Spanning<Directive<'a>>>> {
if parser.peek().item != Token::At { if parser.peek().item != Token::At {
Ok(None) Ok(None)
} }
@ -306,7 +306,7 @@ fn parse_directives<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Vec<Sp
} }
} }
fn parse_directive<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Directive> { fn parse_directive<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Directive<'a>> {
let Spanning { start: start_pos, .. } = try!(parser.expect(&Token::At)); let Spanning { start: start_pos, .. } = try!(parser.expect(&Token::At));
let name = try!(parser.expect_name()); let name = try!(parser.expect_name());
let arguments = try!(parse_arguments(parser)); let arguments = try!(parse_arguments(parser));
@ -315,7 +315,7 @@ fn parse_directive<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Directive> {
&start_pos, &start_pos,
&arguments.as_ref().map_or(&name.end, |s| &s.end).clone(), &arguments.as_ref().map_or(&name.end, |s| &s.end).clone(),
Directive { Directive {
name: name.map(|s| s.to_owned()), name: name,
arguments: arguments, arguments: arguments,
})) }))
} }

View file

@ -44,7 +44,7 @@ fn simple_ast() {
name: Spanning::start_end( name: Spanning::start_end(
&SourcePosition::new(31, 2, 16), &SourcePosition::new(31, 2, 16),
&SourcePosition::new(35, 2, 20), &SourcePosition::new(35, 2, 20),
"node".to_owned()), "node"),
arguments: Some(Spanning::start_end( arguments: Some(Spanning::start_end(
&SourcePosition::new(35, 2, 20), &SourcePosition::new(35, 2, 20),
&SourcePosition::new(42, 2, 27), &SourcePosition::new(42, 2, 27),
@ -54,7 +54,7 @@ fn simple_ast() {
Spanning::start_end( Spanning::start_end(
&SourcePosition::new(36, 2, 21), &SourcePosition::new(36, 2, 21),
&SourcePosition::new(38, 2, 23), &SourcePosition::new(38, 2, 23),
"id".to_owned()), "id"),
Spanning::start_end( Spanning::start_end(
&SourcePosition::new(40, 2, 25), &SourcePosition::new(40, 2, 25),
&SourcePosition::new(41, 2, 26), &SourcePosition::new(41, 2, 26),
@ -73,7 +73,7 @@ fn simple_ast() {
name: Spanning::start_end( name: Spanning::start_end(
&SourcePosition::new(65, 3, 20), &SourcePosition::new(65, 3, 20),
&SourcePosition::new(67, 3, 22), &SourcePosition::new(67, 3, 22),
"id".to_owned()), "id"),
arguments: None, arguments: None,
directives: None, directives: None,
selection_set: None, selection_set: None,
@ -87,7 +87,7 @@ fn simple_ast() {
name: Spanning::start_end( name: Spanning::start_end(
&SourcePosition::new(88, 4, 20), &SourcePosition::new(88, 4, 20),
&SourcePosition::new(92, 4, 24), &SourcePosition::new(92, 4, 24),
"name".to_owned()), "name"),
arguments: None, arguments: None,
directives: None, directives: None,
selection_set: None, selection_set: None,

View file

@ -307,16 +307,16 @@ fn resolve_selection_set_into<T, CtxT>(
let response_name = &f.alias.as_ref().unwrap_or(&f.name).item; let response_name = &f.alias.as_ref().unwrap_or(&f.name).item;
if &f.name.item == "__typename" { if f.name.item == "__typename" {
result.insert( result.insert(
response_name.clone(), (*response_name).to_owned(),
Value::string( Value::string(
instance.concrete_type_name(executor.context()))); instance.concrete_type_name(executor.context())));
continue; continue;
} }
let meta_field = meta_type.field_by_name(&f.name.item) let meta_field = meta_type.field_by_name(&f.name.item)
.expect(&format!("Field {} not found on type {:?}", f.name.item, meta_type.name())); .unwrap_or_else(|| panic!(format!("Field {} not found on type {:?}", f.name.item, meta_type.name())));
let exec_vars = executor.variables(); let exec_vars = executor.variables();
@ -330,15 +330,15 @@ fn resolve_selection_set_into<T, CtxT>(
&Arguments::new( &Arguments::new(
f.arguments.as_ref().map(|m| f.arguments.as_ref().map(|m|
m.item.iter().map(|&(ref k, ref v)| m.item.iter().map(|&(ref k, ref v)|
(k.item.as_str(), v.item.clone().into_const(exec_vars))).collect()), (k.item, v.item.clone().into_const(exec_vars))).collect()),
&meta_field.arguments), &meta_field.arguments),
&mut sub_exec); &mut sub_exec);
match field_result { match field_result {
Ok(v) => merge_key_into(result, response_name.clone(), v), Ok(v) => merge_key_into(result, response_name, v),
Err(e) => { Err(e) => {
sub_exec.push_error(e, start_pos.clone()); sub_exec.push_error(e, start_pos.clone());
result.insert(response_name.clone(), Value::null()); result.insert((*response_name).to_owned(), Value::null());
} }
} }
}, },
@ -415,10 +415,10 @@ fn is_excluded(directives: &Option<Vec<Spanning<Directive>>>, vars: &HashMap<Str
fn merge_key_into( fn merge_key_into(
result: &mut HashMap<String, Value>, result: &mut HashMap<String, Value>,
response_name: String, response_name: &str,
value: Value, value: Value,
) { ) {
match result.entry(response_name) { match result.entry(response_name.to_owned()) {
Entry::Occupied(mut e) => { Entry::Occupied(mut e) => {
println!("Merging object at '{}'", e.key()); println!("Merging object at '{}'", e.key());
match (e.get_mut().as_mut_object_value(), value) { match (e.get_mut().as_mut_object_value(), value) {
@ -442,7 +442,7 @@ fn merge_maps(
) { ) {
for (key, value) in src { for (key, value) in src {
if dest.contains_key(&key) { if dest.contains_key(&key) {
merge_key_into(dest, key, value); merge_key_into(dest, &key, value);
} }
else { else {
dest.insert(key, value); dest.insert(key, value);

View file

@ -23,7 +23,7 @@ pub struct ValidatorContext<'a> {
input_type_stack: Vec<Option<&'a MetaType<'a>>>, input_type_stack: Vec<Option<&'a MetaType<'a>>>,
input_type_literal_stack: Vec<Option<Type<'a>>>, input_type_literal_stack: Vec<Option<Type<'a>>>,
parent_type_stack: Vec<Option<&'a MetaType<'a>>>, parent_type_stack: Vec<Option<&'a MetaType<'a>>>,
fragment_names: HashSet<String>, fragment_names: HashSet<&'a str>,
} }
impl RuleError { impl RuleError {
@ -51,7 +51,7 @@ impl RuleError {
impl<'a> ValidatorContext<'a> { impl<'a> ValidatorContext<'a> {
#[doc(hidden)] #[doc(hidden)]
pub fn new(schema: &'a SchemaType, document: &Document) -> ValidatorContext<'a> { pub fn new(schema: &'a SchemaType, document: &Document<'a>) -> ValidatorContext<'a> {
ValidatorContext { ValidatorContext {
errors: Vec::new(), errors: Vec::new(),
schema: schema, schema: schema,
@ -62,7 +62,7 @@ impl<'a> ValidatorContext<'a> {
input_type_literal_stack: Vec::new(), input_type_literal_stack: Vec::new(),
fragment_names: document.iter() fragment_names: document.iter()
.filter_map(|def| match *def { .filter_map(|def| match *def {
Definition::Fragment(ref frag) => Some(frag.item.name.item.clone()), Definition::Fragment(ref frag) => Some(frag.item.name.item),
_ => None, _ => None,
}) })
.collect() .collect()

View file

@ -47,7 +47,7 @@ fn validate_var_defs(
Some(t) if t.is_input() => { Some(t) if t.is_input() => {
let ct = schema.make_type(&def.var_type.item); let ct = schema.make_type(&def.var_type.item);
if def.var_type.item.is_non_null() && is_absent_or_null(values.get(&name.item)) { if def.var_type.item.is_non_null() && is_absent_or_null(values.get(name.item)) {
errors.push(RuleError::new( errors.push(RuleError::new(
&format!( &format!(
r#"Variable "${}" of required type "{}" was not provided."#, r#"Variable "${}" of required type "{}" was not provided."#,
@ -55,7 +55,7 @@ fn validate_var_defs(
), ),
&[ name.start.clone() ], &[ name.start.clone() ],
)); ));
} else if let Some(ref v) = values.get(&name.item) { } else if let Some(ref v) = values.get(name.item) {
unify_value(&name.item, &name.start, v, &ct, schema, errors, Path::Root); unify_value(&name.item, &name.start, v, &ct, schema, errors, Path::Root);
} }
}, },

View file

@ -46,10 +46,10 @@ impl<'a> Visitor<'a> for MultiVisitor<'a> {
self.visit_all(|v| v.exit_fragment_definition(ctx, f)); self.visit_all(|v| v.exit_fragment_definition(ctx, f));
} }
fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, def: &'a (Spanning<String>, VariableDefinition)) { fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, def: &'a (Spanning<&'a str>, VariableDefinition)) {
self.visit_all(|v| v.enter_variable_definition(ctx, def)); self.visit_all(|v| v.enter_variable_definition(ctx, def));
} }
fn exit_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, def: &'a (Spanning<String>, VariableDefinition)) { fn exit_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, def: &'a (Spanning<&'a str>, VariableDefinition)) {
self.visit_all(|v| v.exit_variable_definition(ctx, def)); self.visit_all(|v| v.exit_variable_definition(ctx, def));
} }
@ -60,10 +60,10 @@ impl<'a> Visitor<'a> for MultiVisitor<'a> {
self.visit_all(|v| v.exit_directive(ctx, d)); self.visit_all(|v| v.exit_directive(ctx, d));
} }
fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, arg: &'a (Spanning<String>, Spanning<InputValue>)) { fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, arg: &'a (Spanning<&'a str>, Spanning<InputValue>)) {
self.visit_all(|v| v.enter_argument(ctx, arg)); self.visit_all(|v| v.enter_argument(ctx, arg));
} }
fn exit_argument(&mut self, ctx: &mut ValidatorContext<'a>, arg: &'a (Spanning<String>, Spanning<InputValue>)) { fn exit_argument(&mut self, ctx: &mut ValidatorContext<'a>, arg: &'a (Spanning<&'a str>, Spanning<InputValue>)) {
self.visit_all(|v| v.exit_argument(ctx, arg)); self.visit_all(|v| v.exit_argument(ctx, arg));
} }

View file

@ -35,7 +35,7 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
self.current_args = None; self.current_args = None;
} }
fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, ref arg_value): &'a (Spanning<String>, Spanning<InputValue>)) { fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, ref arg_value): &'a (Spanning<&'a str>, Spanning<InputValue>)) {
if let Some(argument_meta) = self.current_args if let Some(argument_meta) = self.current_args
.and_then(|args| args.iter().filter(|a| a.name == arg_name.item).next()) .and_then(|args| args.iter().filter(|a| a.name == arg_name.item).next())
{ {

View file

@ -12,7 +12,7 @@ pub fn factory() -> DefaultValuesOfCorrectType {
} }
impl<'a> Visitor<'a> for DefaultValuesOfCorrectType { impl<'a> Visitor<'a> for DefaultValuesOfCorrectType {
fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, ref var_def): &'a (Spanning<String>, VariableDefinition)) { fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, ref var_def): &'a (Spanning<&'a str>, VariableDefinition)) {
if let Some(Spanning { item: ref var_value, ref start, .. }) = var_def.default_value { if let Some(Spanning { item: ref var_value, ref start, .. }) = var_def.default_value {
if var_def.var_type.item.is_non_null() { if var_def.var_type.item.is_non_null() {
ctx.report_error( ctx.report_error(

View file

@ -46,7 +46,7 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
self.current_args = None; self.current_args = None;
} }
fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, _): &'a (Spanning<String>, Spanning<InputValue>)) { fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, _): &'a (Spanning<&'a str>, Spanning<InputValue>)) {
if let Some((ref pos, args)) = self.current_args { if let Some((ref pos, args)) = self.current_args {
if args.iter().filter(|a| a.name == arg_name.item).next().is_none() { if args.iter().filter(|a| a.name == arg_name.item).next().is_none() {
let message = match *pos { let message = match *pos {

View file

@ -20,7 +20,7 @@ impl<'a> Visitor<'a> for KnownTypeNames {
validate_type(ctx, &type_cond.item, &type_cond.start); validate_type(ctx, &type_cond.item, &type_cond.start);
} }
fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(_, ref var_def): &'a (Spanning<String>, VariableDefinition)) { fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(_, ref var_def): &'a (Spanning<&'a str>, VariableDefinition)) {
let type_name = var_def.var_type.item.innermost_name(); let type_name = var_def.var_type.item.innermost_name();
validate_type(ctx, &type_name, &var_def.var_type.start); validate_type(ctx, &type_name, &var_def.var_type.start);
} }

View file

@ -55,7 +55,7 @@ impl<'a> Visitor<'a> for NoFragmentCycles<'a> {
} }
fn exit_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, fragment: &'a Spanning<Fragment>) { fn exit_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, fragment: &'a Spanning<Fragment>) {
assert_eq!(Some(fragment.item.name.item.as_str()), self.current_fragment); assert_eq!(Some(fragment.item.name.item), self.current_fragment);
self.current_fragment = None; self.current_fragment = None;
} }

View file

@ -69,7 +69,7 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> {
} }
fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning<Operation>) { fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning<Operation>) {
let op_name = op.item.name.as_ref().map(|s| s.item.as_str()); let op_name = op.item.name.as_ref().map(|s| s.item);
self.current_scope = Some(Scope::Operation(op_name)); self.current_scope = Some(Scope::Operation(op_name));
self.defined_variables.insert(op_name, (op.start.clone(), HashSet::new())); self.defined_variables.insert(op_name, (op.start.clone(), HashSet::new()));
} }
@ -86,7 +86,7 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> {
} }
} }
fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<String>, VariableDefinition)) { fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) {
if let Some(Scope::Operation(ref name)) = self.current_scope { if let Some(Scope::Operation(ref name)) = self.current_scope {
if let Some(&mut (_, ref mut vars)) = self.defined_variables.get_mut(name) { if let Some(&mut (_, ref mut vars)) = self.defined_variables.get_mut(name) {
vars.insert(&var_name.item); vars.insert(&var_name.item);
@ -94,7 +94,7 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> {
} }
} }
fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, &(_, ref value): &'a (Spanning<String>, Spanning<InputValue>)) { fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, &(_, ref value): &'a (Spanning<&'a str>, Spanning<InputValue>)) {
if let Some(ref scope) = self.current_scope { if let Some(ref scope) = self.current_scope {
self.used_variables self.used_variables
.entry(scope.clone()) .entry(scope.clone())

View file

@ -49,7 +49,7 @@ impl<'a> Visitor<'a> for NoUnusedFragments<'a> {
for def in defs { for def in defs {
if let Definition::Operation(Spanning { item: Operation { ref name, .. }, ..}) = *def { if let Definition::Operation(Spanning { item: Operation { ref name, .. }, ..}) = *def {
let op_name = name.as_ref().map(|s| s.item.as_str()); let op_name = name.as_ref().map(|s| s.item);
self.find_reachable_fragments(&Scope::Operation(op_name), &mut reachable); self.find_reachable_fragments(&Scope::Operation(op_name), &mut reachable);
} }
} }

View file

@ -10,7 +10,7 @@ pub enum Scope<'a> {
} }
pub struct NoUnusedVariables<'a> { pub struct NoUnusedVariables<'a> {
defined_variables: HashMap<Option<&'a str>, HashSet<&'a Spanning<String>>>, defined_variables: HashMap<Option<&'a str>, HashSet<&'a Spanning<&'a str>>>,
used_variables: HashMap<Scope<'a>, Vec<&'a str>>, used_variables: HashMap<Scope<'a>, Vec<&'a str>>,
current_scope: Option<Scope<'a>>, current_scope: Option<Scope<'a>>,
spreads: HashMap<Scope<'a>, Vec<&'a str>>, spreads: HashMap<Scope<'a>, Vec<&'a str>>,
@ -56,13 +56,13 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
let mut visited = HashSet::new(); let mut visited = HashSet::new();
self.find_used_vars( self.find_used_vars(
&Scope::Operation(op_name.clone()), &Scope::Operation(op_name.clone()),
&def_vars.iter().map(|def| def.item.as_str()).collect(), &def_vars.iter().map(|def| def.item).collect(),
&mut used, &mut used,
&mut visited); &mut visited);
ctx.append_errors(def_vars ctx.append_errors(def_vars
.iter() .iter()
.filter(|var| !used.contains(var.item.as_str())) .filter(|var| !used.contains(var.item))
.map(|var| RuleError::new( .map(|var| RuleError::new(
&error_message(&var.item, op_name.clone()), &error_message(&var.item, op_name.clone()),
&[var.start.clone()])) &[var.start.clone()]))
@ -71,7 +71,7 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
} }
fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning<Operation>) { fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning<Operation>) {
let op_name = op.item.name.as_ref().map(|s| s.item.as_str()); let op_name = op.item.name.as_ref().map(|s| s.item);
self.current_scope = Some(Scope::Operation(op_name.clone())); self.current_scope = Some(Scope::Operation(op_name.clone()));
self.defined_variables.insert(op_name, HashSet::new()); self.defined_variables.insert(op_name, HashSet::new());
} }
@ -88,7 +88,7 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
} }
} }
fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<String>, VariableDefinition)) { fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) {
if let Some(Scope::Operation(ref name)) = self.current_scope { if let Some(Scope::Operation(ref name)) = self.current_scope {
if let Some(vars) = self.defined_variables.get_mut(name) { if let Some(vars) = self.defined_variables.get_mut(name) {
vars.insert(var_name); vars.insert(var_name);
@ -96,7 +96,7 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
} }
} }
fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, &(_, ref value): &'a (Spanning<String>, Spanning<InputValue>)) { fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, &(_, ref value): &'a (Spanning<&'a str>, Spanning<InputValue>)) {
if let Some(ref scope) = self.current_scope { if let Some(ref scope) = self.current_scope {
self.used_variables self.used_variables
.entry(scope.clone()) .entry(scope.clone())

View file

@ -14,7 +14,7 @@ struct Conflict(ConflictReason, Vec<SourcePosition>, Vec<SourcePosition>);
struct ConflictReason(String, ConflictReasonMessage); struct ConflictReason(String, ConflictReasonMessage);
#[derive(Debug)] #[derive(Debug)]
struct AstAndDef<'a>(Option<&'a str>, &'a Spanning<Field>, Option<&'a FieldType<'a>>); struct AstAndDef<'a>(Option<&'a str>, &'a Spanning<Field<'a>>, Option<&'a FieldType<'a>>);
type AstAndDefCollection<'a> = OrderedMap<&'a str, Vec<AstAndDef<'a>>>; type AstAndDefCollection<'a> = OrderedMap<&'a str, Vec<AstAndDef<'a>>>;
@ -116,7 +116,7 @@ impl<'a> PairSet<'a> {
} }
pub struct OverlappingFieldsCanBeMerged<'a> { pub struct OverlappingFieldsCanBeMerged<'a> {
named_fragments: HashMap<&'a str, &'a Fragment>, named_fragments: HashMap<&'a str, &'a Fragment<'a>>,
compared_fragments: RefCell<PairSet<'a>>, compared_fragments: RefCell<PairSet<'a>>,
} }
@ -573,11 +573,11 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
let field_def = parent_type.and_then(|t| t.field_by_name(field_name)); let field_def = parent_type.and_then(|t| t.field_by_name(field_name));
let response_name = f.item.alias.as_ref().map(|s| &s.item).unwrap_or_else(|| &field_name); let response_name = f.item.alias.as_ref().map(|s| &s.item).unwrap_or_else(|| &field_name);
if !ast_and_defs.contains_key(response_name.as_str()) { if !ast_and_defs.contains_key(response_name) {
ast_and_defs.insert(response_name, Vec::new()); ast_and_defs.insert(response_name, Vec::new());
} }
ast_and_defs.get_mut(response_name.as_str()).unwrap() ast_and_defs.get_mut(response_name).unwrap()
.push(AstAndDef(parent_type.and_then(MetaType::name), f, field_def)); .push(AstAndDef(parent_type.and_then(MetaType::name), f, field_def));
}, },
Selection::FragmentSpread(Spanning { item: FragmentSpread { ref name, ..}, ..}) => { Selection::FragmentSpread(Spanning { item: FragmentSpread { ref name, ..}, ..}) => {

View file

@ -42,7 +42,7 @@ impl<'a> Visitor<'a> for PossibleFragmentSpreads<'a> {
fn enter_fragment_spread(&mut self, ctx: &mut ValidatorContext<'a>, spread: &'a Spanning<FragmentSpread>) { fn enter_fragment_spread(&mut self, ctx: &mut ValidatorContext<'a>, spread: &'a Spanning<FragmentSpread>) {
if let (Some(ref parent_type), Some(ref frag_type)) if let (Some(ref parent_type), Some(ref frag_type))
= (ctx.parent_type(), self.fragment_types.get(spread.item.name.item.as_str())) = (ctx.parent_type(), self.fragment_types.get(spread.item.name.item))
{ {
if !ctx.schema.type_overlap(parent_type, frag_type) { if !ctx.schema.type_overlap(parent_type, frag_type) {
ctx.report_error( ctx.report_error(

View file

@ -23,7 +23,7 @@ impl<'a> Visitor<'a> for UniqueArgumentNames<'a> {
self.known_names = HashMap::new(); self.known_names = HashMap::new();
} }
fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, _): &'a (Spanning<String>, Spanning<InputValue>)) { fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, _): &'a (Spanning<&'a str>, Spanning<InputValue>)) {
match self.known_names.entry(&arg_name.item) { match self.known_names.entry(&arg_name.item) {
Entry::Occupied(e) => { Entry::Occupied(e) => {
ctx.report_error( ctx.report_error(

View file

@ -19,7 +19,7 @@ impl<'a> Visitor<'a> for UniqueVariableNames<'a> {
self.names = HashMap::new(); self.names = HashMap::new();
} }
fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<String>, VariableDefinition)) { fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) {
match self.names.entry(&var_name.item) { match self.names.entry(&var_name.item) {
Entry::Occupied(e) => { Entry::Occupied(e) => {
ctx.report_error( ctx.report_error(

View file

@ -9,7 +9,7 @@ pub fn factory() -> UniqueVariableNames {
} }
impl<'a> Visitor<'a> for UniqueVariableNames { impl<'a> Visitor<'a> for UniqueVariableNames {
fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, ref var_def): &'a (Spanning<String>, VariableDefinition)) { fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, ref var_def): &'a (Spanning<&'a str>, VariableDefinition)) {
if let Some(var_type) = ctx.schema.concrete_type_by_name(var_def.var_type.item.innermost_name()) { if let Some(var_type) = ctx.schema.concrete_type_by_name(var_def.var_type.item.innermost_name()) {
if !var_type.is_input() { if !var_type.is_input() {
ctx.report_error( ctx.report_error(

View file

@ -13,7 +13,7 @@ pub enum Scope<'a> {
pub struct VariableInAllowedPosition<'a> { pub struct VariableInAllowedPosition<'a> {
spreads: HashMap<Scope<'a>, HashSet<&'a str>>, spreads: HashMap<Scope<'a>, HashSet<&'a str>>,
variable_usages: HashMap<Scope<'a>, Vec<(Spanning<&'a String>, Type<'a>)>>, variable_usages: HashMap<Scope<'a>, Vec<(Spanning<&'a String>, Type<'a>)>>,
variable_defs: HashMap<Scope<'a>, Vec<&'a (Spanning<String>, VariableDefinition<'a>)>>, variable_defs: HashMap<Scope<'a>, Vec<&'a (Spanning<&'a str>, VariableDefinition<'a>)>>,
current_scope: Option<Scope<'a>>, current_scope: Option<Scope<'a>>,
} }
@ -30,7 +30,7 @@ impl<'a> VariableInAllowedPosition<'a> {
fn collect_incorrect_usages( fn collect_incorrect_usages(
&self, &self,
from: &Scope<'a>, from: &Scope<'a>,
var_defs: &Vec<&'a (Spanning<String>, VariableDefinition)>, var_defs: &Vec<&'a (Spanning<&'a str>, VariableDefinition)>,
ctx: &mut ValidatorContext<'a>, ctx: &mut ValidatorContext<'a>,
visited: &mut HashSet<Scope<'a>>, visited: &mut HashSet<Scope<'a>>,
) )
@ -83,7 +83,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
} }
fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning<Operation>) { fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning<Operation>) {
self.current_scope = Some(Scope::Operation(op.item.name.as_ref().map(|s| s.item.as_str()))); self.current_scope = Some(Scope::Operation(op.item.name.as_ref().map(|s| s.item)));
} }
fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, spread: &'a Spanning<FragmentSpread>) { fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, spread: &'a Spanning<FragmentSpread>) {
@ -95,7 +95,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
} }
} }
fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, def: &'a (Spanning<String>, VariableDefinition)) { fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, def: &'a (Spanning<&'a str>, VariableDefinition)) {
if let Some(ref scope) = self.current_scope { if let Some(ref scope) = self.current_scope {
self.variable_defs self.variable_defs
.entry(scope.clone()) .entry(scope.clone())

View file

@ -452,7 +452,7 @@ impl GraphQLType for QueryRoot {
} }
} }
pub fn validate<'a, R, V, F>(r: R, q: &str, factory: F) pub fn validate<'a, R, V, F>(r: R, q: &'a str, factory: F)
-> Vec<RuleError> -> Vec<RuleError>
where R: GraphQLType, where R: GraphQLType,
V: Visitor<'a> + 'a, V: Visitor<'a> + 'a,
@ -479,14 +479,14 @@ pub fn validate<'a, R, V, F>(r: R, q: &str, factory: F)
ctx.into_errors() ctx.into_errors()
} }
pub fn expect_passes_rule<'a, V, F>(factory: F, q: &str) pub fn expect_passes_rule<'a, V, F>(factory: F, q: &'a str)
where V: Visitor<'a> + 'a, where V: Visitor<'a> + 'a,
F: Fn() -> V F: Fn() -> V
{ {
expect_passes_rule_with_schema(QueryRoot, factory, q); expect_passes_rule_with_schema(QueryRoot, factory, q);
} }
pub fn expect_passes_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &str) pub fn expect_passes_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &'a str)
where R: GraphQLType, where R: GraphQLType,
V: Visitor<'a> + 'a, V: Visitor<'a> + 'a,
F: Fn() -> V F: Fn() -> V
@ -499,14 +499,14 @@ pub fn expect_passes_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &str)
} }
} }
pub fn expect_fails_rule<'a, V, F>(factory: F, q: &str, expected_errors: &[RuleError]) pub fn expect_fails_rule<'a, V, F>(factory: F, q: &'a str, expected_errors: &[RuleError])
where V: Visitor<'a> + 'a, where V: Visitor<'a> + 'a,
F: Fn() -> V F: Fn() -> V
{ {
expect_fails_rule_with_schema(QueryRoot, factory, q, expected_errors); expect_fails_rule_with_schema(QueryRoot, factory, q, expected_errors);
} }
pub fn expect_fails_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &str, expected_errors: &[RuleError]) pub fn expect_fails_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &'a str, expected_errors: &[RuleError])
where R: GraphQLType, where R: GraphQLType,
V: Visitor<'a> + 'a, V: Visitor<'a> + 'a,
F: Fn() -> V F: Fn() -> V

View file

@ -15,14 +15,14 @@ pub trait Visitor<'a> {
fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Fragment>) {} fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Fragment>) {}
fn exit_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Fragment>) {} fn exit_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Fragment>) {}
fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<String>, VariableDefinition)) {} fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<&'a str>, VariableDefinition)) {}
fn exit_variable_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<String>, VariableDefinition)) {} fn exit_variable_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<&'a str>, VariableDefinition)) {}
fn enter_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Directive>) {} fn enter_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Directive>) {}
fn exit_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Directive>) {} fn exit_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Directive>) {}
fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<String>, Spanning<InputValue>)) {} fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<&'a str>, Spanning<InputValue>)) {}
fn exit_argument(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<String>, Spanning<InputValue>)) {} fn exit_argument(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<&'a str>, Spanning<InputValue>)) {}
fn enter_selection_set(&mut self, _: &mut ValidatorContext<'a>, _: &'a Vec<Selection>) {} fn enter_selection_set(&mut self, _: &mut ValidatorContext<'a>, _: &'a Vec<Selection>) {}
fn exit_selection_set(&mut self, _: &mut ValidatorContext<'a>, _: &'a Vec<Selection>) {} fn exit_selection_set(&mut self, _: &mut ValidatorContext<'a>, _: &'a Vec<Selection>) {}

View file

@ -161,8 +161,6 @@ fn visit_fragment_spread<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorConte
} }
fn visit_inline_fragment<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, fragment: &'a Spanning<InlineFragment>) { fn visit_inline_fragment<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, fragment: &'a Spanning<InlineFragment>) {
let type_name = fragment.item.type_condition.as_ref().map(|s| s.item.as_str());
let mut visit_fn = move |ctx: &mut ValidatorContext<'a>| { let mut visit_fn = move |ctx: &mut ValidatorContext<'a>| {
v.enter_inline_fragment(ctx, fragment); v.enter_inline_fragment(ctx, fragment);
@ -172,7 +170,7 @@ fn visit_inline_fragment<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorConte
v.exit_inline_fragment(ctx, fragment); v.exit_inline_fragment(ctx, fragment);
}; };
if let Some(type_name) = type_name { if let &Some(Spanning { item: ref type_name, .. }) = &fragment.item.type_condition {
ctx.with_pushed_type(Some(&Type::NonNullNamed(type_name)), visit_fn); ctx.with_pushed_type(Some(&Type::NonNullNamed(type_name)), visit_fn);
} }
else { else {