This commit is contained in:
Koxiaet 2020-09-08 09:30:29 +01:00
parent 47259548c4
commit 04c898ef01
26 changed files with 498 additions and 246 deletions

View File

@ -8,12 +8,18 @@ use super::*;
pub fn parse_query<T: AsRef<str>>(input: T) -> Result<ExecutableDocument> {
let mut pc = PositionCalculator::new(input.as_ref());
Ok(parse_executable_document(
exactly_one(GraphQLParser::parse(Rule::executable_document, input.as_ref())?),
exactly_one(GraphQLParser::parse(
Rule::executable_document,
input.as_ref(),
)?),
&mut pc,
)?)
}
fn parse_executable_document(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<ExecutableDocument> {
fn parse_executable_document(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<ExecutableDocument> {
debug_assert_eq!(pair.as_rule(), Rule::executable_document);
Ok(ExecutableDocument {
@ -25,13 +31,20 @@ fn parse_executable_document(pair: Pair<Rule>, pc: &mut PositionCalculator) -> R
})
}
fn parse_executable_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<ExecutableDefinition> {
fn parse_executable_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<ExecutableDefinition> {
debug_assert_eq!(pair.as_rule(), Rule::executable_definition);
let pair = exactly_one(pair.into_inner());
Ok(match pair.as_rule() {
Rule::operation_definition => ExecutableDefinition::Operation(parse_operation_definition(pair, pc)?),
Rule::fragment_definition => ExecutableDefinition::Fragment(parse_fragment_definition(pair, pc)?),
Rule::operation_definition => {
ExecutableDefinition::Operation(parse_operation_definition(pair, pc)?)
}
Rule::fragment_definition => {
ExecutableDefinition::Fragment(parse_fragment_definition(pair, pc)?)
}
_ => unreachable!(),
})
}
@ -70,7 +83,9 @@ fn parse_named_operation_definition(
let ty = parse_operation_type(pairs.next().unwrap(), pc)?;
let name = parse_if_rule(&mut pairs, Rule::name, |pair| parse_name(pair, pc))?;
let variable_definitions = parse_if_rule(&mut pairs, Rule::variable_definitions, |pair| parse_variable_definitions(pair, pc))?;
let variable_definitions = parse_if_rule(&mut pairs, Rule::variable_definitions, |pair| {
parse_variable_definitions(pair, pc)
})?;
let directives = parse_opt_directives(&mut pairs, pc)?;
let selection_set = parse_selection_set(pairs.next().unwrap(), pc)?;
@ -107,7 +122,9 @@ fn parse_variable_definition(
let variable = parse_variable(pairs.next().unwrap(), pc)?;
let var_type = parse_type(pairs.next().unwrap(), pc)?;
let default_value = parse_if_rule(&mut pairs, Rule::default_value, |pair| parse_default_value(pair, pc))?;
let default_value = parse_if_rule(&mut pairs, Rule::default_value, |pair| {
parse_default_value(pair, pc)
})?;
debug_assert_eq!(pairs.next(), None);
@ -121,7 +138,10 @@ fn parse_variable_definition(
))
}
fn parse_selection_set(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<SelectionSet>> {
fn parse_selection_set(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<SelectionSet>> {
debug_assert_eq!(pair.as_rule(), Rule::selection_set);
let pos = pc.step(&pair);
@ -162,10 +182,13 @@ fn parse_field(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Position
let alias = parse_if_rule(&mut pairs, Rule::alias, |pair| parse_alias(pair, pc))?;
let name = parse_name(pairs.next().unwrap(), pc)?;
let arguments = parse_if_rule(&mut pairs, Rule::arguments, |pair| parse_arguments(pair, pc))?;
let arguments = parse_if_rule(&mut pairs, Rule::arguments, |pair| {
parse_arguments(pair, pc)
})?;
let directives = parse_opt_directives(&mut pairs, pc)?;
let selection_set =
parse_if_rule(&mut pairs, Rule::selection_set, |pair| parse_selection_set(pair, pc))?;
let selection_set = parse_if_rule(&mut pairs, Rule::selection_set, |pair| {
parse_selection_set(pair, pc)
})?;
debug_assert_eq!(pairs.next(), None);
@ -186,7 +209,6 @@ fn parse_alias(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Position
parse_name(exactly_one(pair.into_inner()), pc)
}
fn parse_fragment_spread(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
@ -219,8 +241,9 @@ fn parse_inline_fragment(
let pos = pc.step(&pair);
let mut pairs = pair.into_inner();
let type_condition =
parse_if_rule(&mut pairs, Rule::type_condition, |pair| parse_type_condition(pair, pc))?;
let type_condition = parse_if_rule(&mut pairs, Rule::type_condition, |pair| {
parse_type_condition(pair, pc)
})?;
let directives = parse_opt_directives(&mut pairs, pc)?;
let selection_set = parse_selection_set(pairs.next().unwrap(), pc)?;
@ -287,8 +310,11 @@ mod tests {
fn test_parser() {
for entry in fs::read_dir("tests/executables").unwrap() {
if let Ok(entry) = entry {
GraphQLParser::parse(Rule::executable_document, &fs::read_to_string(entry.path()).unwrap())
.unwrap();
GraphQLParser::parse(
Rule::executable_document,
&fs::read_to_string(entry.path()).unwrap(),
)
.unwrap();
}
}
}

View File

@ -2,9 +2,9 @@
//!
//! This module's structure mirrors `types`.
use crate::pos::{Positioned, PositionCalculator};
use crate::pos::{PositionCalculator, Positioned};
use crate::types::*;
use crate::{Result, Error};
use crate::{Error, Result};
use pest::iterators::{Pair, Pairs};
use pest::Parser;
use pest_derive::Parser;
@ -40,7 +40,10 @@ fn parse_operation_type(
))
}
fn parse_default_value(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<ConstValue>> {
fn parse_default_value(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<ConstValue>> {
debug_assert_eq!(pair.as_rule(), Rule::default_value);
parse_const_value(exactly_one(pair.into_inner()), pc)
@ -49,10 +52,16 @@ fn parse_default_value(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<
fn parse_type(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<Type>> {
debug_assert_eq!(pair.as_rule(), Rule::type_);
Ok(Positioned::new(Type::new(pair.as_str()).unwrap(), pc.step(&pair)))
Ok(Positioned::new(
Type::new(pair.as_str()).unwrap(),
pc.step(&pair),
))
}
fn parse_const_value(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<ConstValue>> {
fn parse_const_value(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<ConstValue>> {
debug_assert_eq!(pair.as_rule(), Rule::const_value);
let pos = pc.step(&pair);
@ -138,46 +147,73 @@ fn parse_variable(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Posit
fn parse_number(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<Number>> {
debug_assert_eq!(pair.as_rule(), Rule::number);
let pos = pc.step(&pair);
Ok(Positioned::new(pair.as_str().parse().expect("failed to parse number"), pos))
Ok(Positioned::new(
pair.as_str().parse().expect("failed to parse number"),
pos,
))
}
fn parse_string(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<String>> {
debug_assert_eq!(pair.as_rule(), Rule::string);
let pos = pc.step(&pair);
let pair = exactly_one(pair.into_inner());
Ok(Positioned::new(match pair.as_rule() {
Rule::block_string_content => block_string_value(pair.as_str()),
Rule::string_content => string_value(pair.as_str()),
_ => unreachable!(),
}, pos))
Ok(Positioned::new(
match pair.as_rule() {
Rule::block_string_content => block_string_value(pair.as_str()),
Rule::string_content => string_value(pair.as_str()),
_ => unreachable!(),
},
pos,
))
}
fn parse_boolean(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<bool>> {
debug_assert_eq!(pair.as_rule(), Rule::boolean);
let pos = pc.step(&pair);
Ok(Positioned::new(match pair.as_str() {
"true" => true,
"false" => false,
_ => unreachable!(),
}, pos))
Ok(Positioned::new(
match pair.as_str() {
"true" => true,
"false" => false,
_ => unreachable!(),
},
pos,
))
}
fn parse_enum_value(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<Name>> {
debug_assert_eq!(pair.as_rule(), Rule::enum_value);
parse_name(exactly_one(pair.into_inner()), pc)
}
fn parse_opt_const_directives<'a>(pairs: &mut Pairs<'a, Rule>, pc: &mut PositionCalculator) -> Result<Vec<Positioned<ConstDirective>>> {
Ok(parse_if_rule(pairs, Rule::const_directives, |pair| parse_const_directives(pair, pc))?.unwrap_or_default())
fn parse_opt_const_directives<'a>(
pairs: &mut Pairs<'a, Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<Positioned<ConstDirective>>> {
Ok(parse_if_rule(pairs, Rule::const_directives, |pair| {
parse_const_directives(pair, pc)
})?
.unwrap_or_default())
}
fn parse_opt_directives<'a>(pairs: &mut Pairs<'a, Rule>, pc: &mut PositionCalculator) -> Result<Vec<Positioned<Directive>>> {
Ok(parse_if_rule(pairs, Rule::directives, |pair| parse_directives(pair, pc))?.unwrap_or_default())
fn parse_opt_directives<'a>(
pairs: &mut Pairs<'a, Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<Positioned<Directive>>> {
Ok(
parse_if_rule(pairs, Rule::directives, |pair| parse_directives(pair, pc))?
.unwrap_or_default(),
)
}
fn parse_const_directives(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Vec<Positioned<ConstDirective>>> {
fn parse_const_directives(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<Positioned<ConstDirective>>> {
debug_assert_eq!(pair.as_rule(), Rule::const_directives);
pair.into_inner()
.map(|pair| parse_const_directive(pair, pc))
.collect()
}
fn parse_directives(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Vec<Positioned<Directive>>> {
fn parse_directives(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<Positioned<Directive>>> {
debug_assert_eq!(pair.as_rule(), Rule::directives);
pair.into_inner()
@ -185,14 +221,19 @@ fn parse_directives(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Vec
.collect()
}
fn parse_const_directive(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<ConstDirective>> {
fn parse_const_directive(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<ConstDirective>> {
debug_assert_eq!(pair.as_rule(), Rule::const_directive);
let pos = pc.step(&pair);
let mut pairs = pair.into_inner();
let name = parse_name(pairs.next().unwrap(), pc)?;
let arguments = parse_if_rule(&mut pairs, Rule::const_arguments, |pair| parse_const_arguments(pair, pc))?;
let arguments = parse_if_rule(&mut pairs, Rule::const_arguments, |pair| {
parse_const_arguments(pair, pc)
})?;
debug_assert_eq!(pairs.next(), None);
@ -211,7 +252,9 @@ fn parse_directive(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Posi
let mut pairs = pair.into_inner();
let name = parse_name(pairs.next().unwrap(), pc)?;
let arguments = parse_if_rule(&mut pairs, Rule::arguments, |pair| parse_arguments(pair, pc))?;
let arguments = parse_if_rule(&mut pairs, Rule::arguments, |pair| {
parse_arguments(pair, pc)
})?;
debug_assert_eq!(pairs.next(), None);
@ -265,5 +308,8 @@ fn parse_arguments(
fn parse_name(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<Name>> {
debug_assert_eq!(pair.as_rule(), Rule::name);
Ok(Positioned::new(Name::new_unchecked(pair.as_str().to_owned()), pc.step(&pair)))
Ok(Positioned::new(
Name::new_unchecked(pair.as_str().to_owned()),
pc.step(&pair),
))
}

View File

@ -8,12 +8,18 @@ use super::*;
pub fn parse_schema<T: AsRef<str>>(input: T) -> Result<ServiceDocument> {
let mut pc = PositionCalculator::new(input.as_ref());
Ok(parse_service_document(
exactly_one(GraphQLParser::parse(Rule::service_document, input.as_ref())?),
exactly_one(GraphQLParser::parse(
Rule::service_document,
input.as_ref(),
)?),
&mut pc,
)?)
}
fn parse_service_document(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<ServiceDocument> {
fn parse_service_document(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<ServiceDocument> {
debug_assert_eq!(pair.as_rule(), Rule::service_document);
Ok(ServiceDocument {
@ -25,19 +31,27 @@ fn parse_service_document(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Resu
})
}
fn parse_type_system_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<TypeSystemDefinition> {
fn parse_type_system_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<TypeSystemDefinition> {
debug_assert_eq!(pair.as_rule(), Rule::type_system_definition);
let pair = exactly_one(pair.into_inner());
Ok(match pair.as_rule() {
Rule::schema_definition => TypeSystemDefinition::Schema(parse_schema_definition(pair, pc)?),
Rule::type_definition => TypeSystemDefinition::Type(parse_type_definition(pair, pc)?),
Rule::directive_definition => TypeSystemDefinition::Directive(parse_directive_definition(pair, pc)?),
Rule::directive_definition => {
TypeSystemDefinition::Directive(parse_directive_definition(pair, pc)?)
}
_ => unreachable!(),
})
}
fn parse_schema_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<SchemaDefinition>> {
fn parse_schema_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<SchemaDefinition>> {
debug_assert_eq!(pair.as_rule(), Rule::schema_definition);
let pos = pc.step(&pair);
@ -86,16 +100,22 @@ fn parse_schema_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Res
return Err(Error::new("missing query root", pos));
}
Ok(Positioned::new(SchemaDefinition {
extend,
directives,
query,
mutation,
subscription,
}, pos))
Ok(Positioned::new(
SchemaDefinition {
extend,
directives,
query,
mutation,
subscription,
},
pos,
))
}
fn parse_type_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<TypeDefinition>> {
fn parse_type_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<TypeDefinition>> {
debug_assert_eq!(pair.as_rule(), Rule::type_definition);
let pos = pc.step(&pair);
@ -123,16 +143,25 @@ fn parse_type_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Resul
let directives = parse_opt_const_directives(&mut pairs, pc)?;
let fields = parse_if_rule(&mut pairs, Rule::fields_definition, |pair| parse_fields_definition(pair, pc))?.unwrap_or_default();
let fields = parse_if_rule(&mut pairs, Rule::fields_definition, |pair| {
parse_fields_definition(pair, pc)
})?
.unwrap_or_default();
(directives, TypeKind::Object(ObjectType {
implements: implements.unwrap_or_default(),
fields,
}))
(
directives,
TypeKind::Object(ObjectType {
implements: implements.unwrap_or_default(),
fields,
}),
)
}
Rule::interface_type => {
let directives = parse_opt_const_directives(&mut pairs, pc)?;
let fields = parse_if_rule(&mut pairs, Rule::fields_definition, |pair| parse_fields_definition(pair, pc))?.unwrap_or_default();
let fields = parse_if_rule(&mut pairs, Rule::fields_definition, |pair| {
parse_fields_definition(pair, pc)
})?
.unwrap_or_default();
(directives, TypeKind::Interface(InterfaceType { fields }))
}
Rule::union_type => {
@ -140,10 +169,9 @@ fn parse_type_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Resul
let members = parse_if_rule(&mut pairs, Rule::union_member_types, |pair| {
debug_assert_eq!(pair.as_rule(), Rule::union_member_types);
pair.into_inner()
.map(|pair| parse_name(pair, pc))
.collect()
})?.unwrap_or_default();
pair.into_inner().map(|pair| parse_name(pair, pc)).collect()
})?
.unwrap_or_default();
(directives, TypeKind::Union(UnionType { members }))
}
Rule::enum_type => {
@ -158,20 +186,25 @@ fn parse_type_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Resul
let pos = pc.step(&pair);
let mut pairs = pair.into_inner();
let description = parse_if_rule(&mut pairs, Rule::string, |pair| parse_string(pair, pc))?;
let description =
parse_if_rule(&mut pairs, Rule::string, |pair| parse_string(pair, pc))?;
let value = parse_enum_value(pairs.next().unwrap(), pc)?;
let directives = parse_opt_const_directives(&mut pairs, pc)?;
debug_assert_eq!(pairs.next(), None);
Ok(Positioned::new(EnumValueDefinition {
description,
value,
directives,
}, pos))
Ok(Positioned::new(
EnumValueDefinition {
description,
value,
directives,
},
pos,
))
})
.collect()
})?.unwrap_or_default();
})?
.unwrap_or_default();
(directives, TypeKind::Enum(EnumType { values }))
}
Rule::input_object_type => {
@ -179,35 +212,49 @@ fn parse_type_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Resul
let fields = parse_if_rule(&mut pairs, Rule::input_fields_definition, |pair| {
debug_assert_eq!(pair.as_rule(), Rule::input_fields_definition);
pair
.into_inner()
pair.into_inner()
.map(|pair| parse_input_value_definition(pair, pc))
.collect()
})?.unwrap_or_default();
})?
.unwrap_or_default();
(directives, TypeKind::InputObject(InputObjectType { fields }))
(
directives,
TypeKind::InputObject(InputObjectType { fields }),
)
}
_ => unreachable!(),
};
debug_assert_eq!(pairs.next(), None);
Ok(Positioned::new(TypeDefinition {
extend,
description,
name,
directives,
kind,
}, pos))
Ok(Positioned::new(
TypeDefinition {
extend,
description,
name,
directives,
kind,
},
pos,
))
}
fn parse_fields_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Vec<Positioned<FieldDefinition>>> {
fn parse_fields_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<Positioned<FieldDefinition>>> {
debug_assert_eq!(pair.as_rule(), Rule::fields_definition);
pair.into_inner().map(|pair| parse_field_definition(pair, pc)).collect()
pair.into_inner()
.map(|pair| parse_field_definition(pair, pc))
.collect()
}
fn parse_field_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<FieldDefinition>> {
fn parse_field_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<FieldDefinition>> {
debug_assert_eq!(pair.as_rule(), Rule::field_definition);
let pos = pc.step(&pair);
@ -215,16 +262,31 @@ fn parse_field_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Resu
let description = parse_if_rule(&mut pairs, Rule::string, |pair| parse_string(pair, pc))?;
let name = parse_name(pairs.next().unwrap(), pc)?;
let arguments = parse_if_rule(&mut pairs, Rule::arguments_definition, |pair| parse_arguments_definition(pair, pc))?.unwrap_or_default();
let arguments = parse_if_rule(&mut pairs, Rule::arguments_definition, |pair| {
parse_arguments_definition(pair, pc)
})?
.unwrap_or_default();
let ty = parse_type(pairs.next().unwrap(), pc)?;
let directives = parse_opt_const_directives(&mut pairs, pc)?;
debug_assert_eq!(pairs.next(), None);
Ok(Positioned::new(FieldDefinition { description, name, arguments, ty, directives }, pos))
Ok(Positioned::new(
FieldDefinition {
description,
name,
arguments,
ty,
directives,
},
pos,
))
}
fn parse_directive_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<DirectiveDefinition>> {
fn parse_directive_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<DirectiveDefinition>> {
debug_assert_eq!(pair.as_rule(), Rule::directive_definition);
let pos = pc.step(&pair);
@ -234,55 +296,63 @@ fn parse_directive_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) ->
let name = parse_name(pairs.next().unwrap(), pc)?;
let arguments = parse_if_rule(&mut pairs, Rule::arguments_definition, |pair| {
debug_assert_eq!(pair.as_rule(), Rule::arguments_definition);
pair
.into_inner()
pair.into_inner()
.map(|pair| parse_input_value_definition(pair, pc))
.collect()
})?.unwrap_or_default();
})?
.unwrap_or_default();
let locations = {
let pair = pairs.next().unwrap();
debug_assert_eq!(pair.as_rule(), Rule::directive_locations);
pair
.into_inner()
pair.into_inner()
.map(|pair| {
let pos = pc.step(&pair);
debug_assert_eq!(pair.as_rule(), Rule::directive_location);
Positioned::new(match pair.as_str() {
"QUERY" => DirectiveLocation::Query,
"MUTATION" => DirectiveLocation::Mutation,
"SUBSCRIPTION" => DirectiveLocation::Subscription,
"FIELD" => DirectiveLocation::Field,
"FRAGMENT_DEFINITION" => DirectiveLocation::FragmentDefinition,
"FRAGMENT_SPREAD" => DirectiveLocation::FragmentSpread,
"INLINE_FRAGMENT" => DirectiveLocation::InlineFragment,
"SCHEMA" => DirectiveLocation::Schema,
"SCALAR" => DirectiveLocation::Scalar,
"OBJECT" => DirectiveLocation::Object,
"FIELD_DEFINITION" => DirectiveLocation::FieldDefinition,
"ARGUMENT_DEFINITION" => DirectiveLocation::ArgumentDefinition,
"INTERFACE" => DirectiveLocation::Interface,
"UNION" => DirectiveLocation::Union,
"ENUM" => DirectiveLocation::Enum,
"ENUM_VALUE" => DirectiveLocation::EnumValue,
"INPUT_OBJECT" => DirectiveLocation::InputObject,
"INPUT_FIELD_DEFINITION" => DirectiveLocation::InputFieldDefinition,
_ => unreachable!(),
}, pos)
Positioned::new(
match pair.as_str() {
"QUERY" => DirectiveLocation::Query,
"MUTATION" => DirectiveLocation::Mutation,
"SUBSCRIPTION" => DirectiveLocation::Subscription,
"FIELD" => DirectiveLocation::Field,
"FRAGMENT_DEFINITION" => DirectiveLocation::FragmentDefinition,
"FRAGMENT_SPREAD" => DirectiveLocation::FragmentSpread,
"INLINE_FRAGMENT" => DirectiveLocation::InlineFragment,
"SCHEMA" => DirectiveLocation::Schema,
"SCALAR" => DirectiveLocation::Scalar,
"OBJECT" => DirectiveLocation::Object,
"FIELD_DEFINITION" => DirectiveLocation::FieldDefinition,
"ARGUMENT_DEFINITION" => DirectiveLocation::ArgumentDefinition,
"INTERFACE" => DirectiveLocation::Interface,
"UNION" => DirectiveLocation::Union,
"ENUM" => DirectiveLocation::Enum,
"ENUM_VALUE" => DirectiveLocation::EnumValue,
"INPUT_OBJECT" => DirectiveLocation::InputObject,
"INPUT_FIELD_DEFINITION" => DirectiveLocation::InputFieldDefinition,
_ => unreachable!(),
},
pos,
)
})
.collect()
};
debug_assert_eq!(pairs.next(), None);
Ok(Positioned::new(DirectiveDefinition {
description,
name,
arguments,
locations,
}, pos))
Ok(Positioned::new(
DirectiveDefinition {
description,
name,
arguments,
locations,
},
pos,
))
}
fn parse_arguments_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Vec<Positioned<InputValueDefinition>>> {
fn parse_arguments_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<Positioned<InputValueDefinition>>> {
debug_assert_eq!(pair.as_rule(), Rule::arguments_definition);
pair.into_inner()
@ -290,7 +360,10 @@ fn parse_arguments_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) ->
.collect()
}
fn parse_input_value_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<InputValueDefinition>> {
fn parse_input_value_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<InputValueDefinition>> {
debug_assert_eq!(pair.as_rule(), Rule::input_value_definition);
let pos = pc.step(&pair);
@ -299,10 +372,21 @@ fn parse_input_value_definition(pair: Pair<Rule>, pc: &mut PositionCalculator) -
let description = parse_if_rule(&mut pairs, Rule::string, |pair| parse_string(pair, pc))?;
let name = parse_name(pairs.next().unwrap(), pc)?;
let ty = parse_type(pairs.next().unwrap(), pc)?;
let default_value = parse_if_rule(&mut pairs, Rule::default_value, |pair| parse_default_value(pair, pc))?;
let default_value = parse_if_rule(&mut pairs, Rule::default_value, |pair| {
parse_default_value(pair, pc)
})?;
let directives = parse_opt_const_directives(&mut pairs, pc)?;
Ok(Positioned::new(InputValueDefinition { description, name, ty, default_value, directives }, pos))
Ok(Positioned::new(
InputValueDefinition {
description,
name,
ty,
default_value,
directives,
},
pos,
))
}
#[cfg(test)]
@ -314,8 +398,11 @@ mod tests {
fn test_parser() {
for entry in fs::read_dir("tests/services").unwrap() {
if let Ok(entry) = entry {
GraphQLParser::parse(Rule::service_document, &fs::read_to_string(entry.path()).unwrap())
.unwrap();
GraphQLParser::parse(
Rule::service_document,
&fs::read_to_string(entry.path()).unwrap(),
)
.unwrap();
}
}
}

View File

@ -9,7 +9,11 @@ pub(super) fn next_if_rule<'a>(pairs: &mut Pairs<'a, Rule>, rule: Rule) -> Optio
None
}
}
pub(super) fn parse_if_rule<'a, T>(pairs: &mut Pairs<'a, Rule>, rule: Rule, f: impl FnOnce(Pair<Rule>) -> Result<T>) -> Result<Option<T>> {
pub(super) fn parse_if_rule<'a, T>(
pairs: &mut Pairs<'a, Rule>,
rule: Rule,
f: impl FnOnce(Pair<Rule>) -> Result<T>,
) -> Result<Option<T>> {
next_if_rule(pairs, rule).map(f).transpose()
}
@ -20,7 +24,6 @@ pub(super) fn exactly_one<T>(iter: impl IntoIterator<Item = T>) -> T {
res
}
pub(super) fn block_string_value(raw: &str) -> String {
// Split the string by either \r\n, \r or \n
let lines: Vec<_> = raw

View File

@ -1,12 +1,12 @@
use crate::Error;
use pest::iterators::Pair;
use pest::RuleType;
use serde::Serialize;
use std::borrow::{Borrow, BorrowMut};
use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::str::Chars;
use pest::RuleType;
use pest::iterators::Pair;
use crate::Error;
/// Original position of an element in source code.
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash, Serialize)]
@ -47,7 +47,7 @@ impl<T> Positioned<T> {
}
/// Get the inner node.
///
///
/// This is most useful in callback chains where `Positioned::into_inner` is easier to read than
/// `|positioned| positioned.node`.
#[inline]

View File

@ -7,19 +7,19 @@
//! This follows the [June 2018 edition of the GraphQL spec](https://spec.graphql.org/June2018/).
use crate::pos::{Pos, Positioned};
use serde::{Serialize, Deserialize};
use serde::ser::{Serializer, Error as _};
use serde::de::{Deserializer, Error as _, Unexpected};
use serde::ser::{Error as _, Serializer};
use serde::{Deserialize, Serialize};
use std::borrow::Borrow;
use std::collections::{BTreeMap, HashMap};
use std::convert::{TryFrom, TryInto};
use std::fmt::{self, Display, Formatter, Write};
use std::fs::File;
use std::convert::{TryFrom, TryInto};
use std::borrow::Borrow;
use std::ops::Deref;
pub use executable::*;
pub use service::*;
pub use serde_json::Number;
pub use service::*;
mod executable;
mod service;
@ -147,8 +147,14 @@ impl ConstValue {
Self::String(s) => Value::String(s),
Self::Boolean(b) => Value::Boolean(b),
Self::Enum(v) => Value::Enum(v),
Self::List(items) => Value::List(items.into_iter().map(ConstValue::into_value).collect()),
Self::Object(map) => Value::Object(map.into_iter().map(|(key, value)| (key, value.into_value())).collect()),
Self::List(items) => {
Value::List(items.into_iter().map(ConstValue::into_value).collect())
}
Self::Object(map) => Value::Object(
map.into_iter()
.map(|(key, value)| (key, value.into_value()))
.collect(),
),
Self::Upload(upload) => Value::Upload(upload),
}
}
@ -242,11 +248,17 @@ pub enum Value {
impl Value {
/// Attempt to convert the value into a const value by using a function to get a variable.
pub fn into_const_with<E>(self, mut f: impl FnMut(Name) -> Result<ConstValue, E>) -> Result<ConstValue, E> {
pub fn into_const_with<E>(
self,
mut f: impl FnMut(Name) -> Result<ConstValue, E>,
) -> Result<ConstValue, E> {
self.into_const_with_mut(&mut f)
}
fn into_const_with_mut<E>(self, f: &mut impl FnMut(Name) -> Result<ConstValue, E>) -> Result<ConstValue, E> {
fn into_const_with_mut<E>(
self,
f: &mut impl FnMut(Name) -> Result<ConstValue, E>,
) -> Result<ConstValue, E> {
Ok(match self {
Self::Variable(name) => f(name)?,
Self::Null => ConstValue::Null,
@ -254,8 +266,17 @@ impl Value {
Self::String(s) => ConstValue::String(s),
Self::Boolean(b) => ConstValue::Boolean(b),
Self::Enum(v) => ConstValue::Enum(v),
Self::List(items) => ConstValue::List(items.into_iter().map(|value| value.into_const_with_mut(f)).collect::<Result<_, _>>()?),
Self::Object(map) => ConstValue::Object(map.into_iter().map(|(key, value)| Ok((key, value.into_const_with_mut(f)?))).collect::<Result<_, _>>()?),
Self::List(items) => ConstValue::List(
items
.into_iter()
.map(|value| value.into_const_with_mut(f))
.collect::<Result<_, _>>()?,
),
Self::Object(map) => ConstValue::Object(
map.into_iter()
.map(|(key, value)| Ok((key, value.into_const_with_mut(f)?)))
.collect::<Result<_, _>>()?,
),
Self::Upload(upload) => ConstValue::Upload(upload),
})
}
@ -350,7 +371,7 @@ fn write_quoted(s: &str, f: &mut Formatter<'_>) -> fmt::Result {
}
f.write_char('"')
}
fn write_list<T: Display>(list: impl IntoIterator<Item = T>, f: &mut Formatter<'_>) -> fmt::Result {
fn write_list<T: Display>(list: impl IntoIterator<Item = T>, f: &mut Formatter<'_>) -> fmt::Result {
f.write_char('[')?;
for item in list {
item.fmt(f)?;
@ -358,8 +379,11 @@ fn write_quoted(s: &str, f: &mut Formatter<'_>) -> fmt::Result {
}
f.write_char(']')
}
fn write_object<K: Display, V: Display>(object: impl IntoIterator<Item = (K, V)>, f: &mut Formatter<'_>) -> fmt::Result {
f.write_char('{')?;
fn write_object<K: Display, V: Display>(
object: impl IntoIterator<Item = (K, V)>,
f: &mut Formatter<'_>,
) -> fmt::Result {
f.write_char('{')?;
for (name, value) in object {
write!(f, "{}: {},", name, value)?;
}
@ -430,7 +454,11 @@ impl ConstDirective {
pub fn into_directive(self) -> Directive {
Directive {
name: self.name,
arguments: self.arguments.into_iter().map(|(name, value)| (name, value.map(ConstValue::into_value))).collect(),
arguments: self
.arguments
.into_iter()
.map(|(name, value)| (name, value.map(ConstValue::into_value)))
.collect(),
}
}
@ -461,7 +489,13 @@ impl Directive {
pub fn into_const(self) -> Option<ConstDirective> {
Some(ConstDirective {
name: self.name,
arguments: self.arguments.into_iter().map(|(name, value)| Some((name, Positioned::new(value.node.into_const()?, value.pos)))).collect::<Option<_>>()?,
arguments: self
.arguments
.into_iter()
.map(|(name, value)| {
Some((name, Positioned::new(value.node.into_const()?, value.pos)))
})
.collect::<Option<_>>()?,
})
}
@ -488,7 +522,9 @@ impl Name {
#[must_use]
pub fn is_valid(name: &str) -> bool {
let mut bytes = name.bytes();
bytes.next().map_or(false, |c| c.is_ascii_alphabetic() || c == b'_')
bytes
.next()
.map_or(false, |c| c.is_ascii_alphabetic() || c == b'_')
&& bytes.all(|c| c.is_ascii_alphanumeric() || c == b'_')
}
@ -595,7 +631,8 @@ impl<'a> PartialEq<Name> for &'a str {
impl<'de> Deserialize<'de> for Name {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Self::new(String::deserialize(deserializer)?).map_err(|s| D::Error::invalid_value(Unexpected::Str(&s), &"a GraphQL name"))
Self::new(String::deserialize(deserializer)?)
.map_err(|s| D::Error::invalid_value(Unexpected::Str(&s), &"a GraphQL name"))
}
}

View File

@ -1,6 +1,8 @@
use crate::base::Type;
use crate::extensions::Extensions;
use crate::parser::types::{Directive, ExecutableDocumentData, Field, SelectionSet, Value as InputValue, Name};
use crate::parser::types::{
Directive, ExecutableDocumentData, Field, Name, SelectionSet, Value as InputValue,
};
use crate::schema::SchemaEnv;
use crate::{FieldResult, InputValueType, Lookahead, Pos, Positioned, QueryError, Result, Value};
use fnv::FnvHashMap;
@ -368,7 +370,9 @@ impl<'a, T> ContextBase<'a, T> {
fn resolve_input_value(&self, value: Positioned<InputValue>) -> Result<Value> {
let pos = value.pos;
value.node.into_const_with(|name| self.var_value(&name, pos))
value
.node
.into_const_with(|name| self.var_value(&name, pos))
}
#[doc(hidden)]
@ -403,7 +407,8 @@ impl<'a, T> ContextBase<'a, T> {
let pos = condition_input.pos;
let condition_input = self.resolve_input_value(condition_input)?;
if include != <bool as InputValueType>::parse(Some(condition_input))
if include
!= <bool as InputValueType>::parse(Some(condition_input))
.map_err(|e| e.into_error(pos, bool::qualified_type_name()))?
{
return Ok(true);

View File

@ -126,7 +126,12 @@ fn do_resolve<'a, T: ObjectType + Send + Sync>(
pos: fragment_spread.pos,
path: None,
err: QueryError::UnknownFragment {
name: fragment_spread.node.fragment_name.node.clone().into_string(),
name: fragment_spread
.node
.fragment_name
.node
.clone()
.into_string(),
},
});
}

View File

@ -6,7 +6,7 @@ use crate::parser::types::{OperationType, UploadValue};
use crate::registry::CacheControl;
use crate::{
do_resolve, ContextBase, Error, ObjectType, Pos, QueryEnv, QueryError, Result, Schema,
SubscriptionType, Variables,Value
SubscriptionType, Value, Variables,
};
use std::any::Any;
use std::fs::File;

View File

@ -54,7 +54,13 @@ pub fn collect_fields<'a, T: ObjectType + Send + Sync>(
if field.node.name.node == "__typename" {
// Get the typename
let ctx_field = ctx.with_field(field);
let field_name = ctx_field.item.node.response_key().node.clone().into_string();
let field_name = ctx_field
.item
.node
.response_key()
.node
.clone()
.into_string();
futures.push(Box::pin(
future::ok::<serde_json::Value, Error>(
root.introspection_type_name().to_string().into(),
@ -78,7 +84,13 @@ pub fn collect_fields<'a, T: ObjectType + Send + Sync>(
let ctx = ctx.clone();
async move {
let ctx_field = ctx.with_field(field);
let field_name = ctx_field.item.node.response_key().node.clone().into_string();
let field_name = ctx_field
.item
.node
.response_key()
.node
.clone()
.into_string();
let resolve_info = ResolveInfo {
resolve_id: ctx_field.resolve_id,

View File

@ -84,7 +84,8 @@ impl ConnectionTransport for WebSocketTransport {
"start" => {
if let (Some(id), Some(payload)) = (msg.id, msg.payload) {
if let Ok(request) = serde_json::from_value::<GQLRequest>(payload) {
let variables = Variables::parse_from_json(request.variables.unwrap_or_default());
let variables =
Variables::parse_from_json(request.variables.unwrap_or_default());
match schema
.create_subscription_stream(
&request.query,

View File

@ -1,5 +1,5 @@
use crate::context::QueryPathNode;
use crate::parser::types::{Directive, Field, Value, Name};
use crate::parser::types::{Directive, Field, Name, Value};
use crate::registry::MetaInputValue;
use crate::validation::utils::is_valid_input_value;
use crate::validation::visitor::{Visitor, VisitorContext};
@ -42,7 +42,16 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
.current_args
.and_then(|args| args.get(name.node.as_str()).map(|input| input))
{
let value = value.node.clone().into_const_with(|var_name| ctx.variables.and_then(|variables| variables.0.get(&var_name)).map(Clone::clone).ok_or(())).ok();
let value = value
.node
.clone()
.into_const_with(|var_name| {
ctx.variables
.and_then(|variables| variables.0.get(&var_name))
.map(Clone::clone)
.ok_or(())
})
.ok();
if let Some(validator) = &arg.validator {
if let Some(value) = &value {
@ -56,16 +65,18 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
}
}
if let Some(reason) = value.and_then(|value| is_valid_input_value(
ctx.registry,
ctx.variables,
&arg.ty,
&value,
QueryPathNode {
parent: None,
segment: QueryPathSegment::Name(arg.name),
},
)) {
if let Some(reason) = value.and_then(|value| {
is_valid_input_value(
ctx.registry,
ctx.variables,
&arg.ty,
&value,
QueryPathNode {
parent: None,
segment: QueryPathSegment::Name(arg.name),
},
)
}) {
ctx.report_error(
vec![name.pos],
format!("Invalid value for argument {}", reason),

View File

@ -1,4 +1,4 @@
use crate::parser::types::{Directive, Field, Value, Name};
use crate::parser::types::{Directive, Field, Name, Value};
use crate::registry::MetaInputValue;
use crate::validation::suggestion::make_suggestion;
use crate::validation::visitor::{Visitor, VisitorContext};

View File

@ -55,7 +55,11 @@ impl<'a> Visitor<'a> for KnownDirectives {
ctx: &mut VisitorContext<'a>,
directive: &'a Positioned<Directive>,
) {
if let Some(schema_directive) = ctx.registry.directives.get(directive.node.name.node.as_str()) {
if let Some(schema_directive) = ctx
.registry
.directives
.get(directive.node.name.node.as_str())
{
if let Some(current_location) = self.location_stack.last() {
if !schema_directive.locations.contains(current_location) {
ctx.report_error(

View File

@ -1,5 +1,6 @@
use crate::parser::types::{
ExecutableDocument, FragmentDefinition, FragmentSpread, OperationDefinition, VariableDefinition, Value, Name
ExecutableDocument, FragmentDefinition, FragmentSpread, Name, OperationDefinition, Value,
VariableDefinition,
};
use crate::validation::utils::{referenced_variables, Scope};
use crate::validation::visitor::{Visitor, VisitorContext};

View File

@ -1,5 +1,6 @@
use crate::parser::types::{
ExecutableDefinition, ExecutableDocument, FragmentDefinition, FragmentSpread, OperationDefinition,
ExecutableDefinition, ExecutableDocument, FragmentDefinition, FragmentSpread,
OperationDefinition,
};
use crate::validation::utils::Scope;
use crate::validation::visitor::{Visitor, VisitorContext};

View File

@ -1,5 +1,6 @@
use crate::parser::types::{
ExecutableDocument, FragmentDefinition, FragmentSpread, OperationDefinition, VariableDefinition, Value, Name
ExecutableDocument, FragmentDefinition, FragmentSpread, Name, OperationDefinition, Value,
VariableDefinition,
};
use crate::validation::utils::{referenced_variables, Scope};
use crate::validation::visitor::{Visitor, VisitorContext};

View File

@ -1,4 +1,6 @@
use crate::parser::types::{ExecutableDefinition, ExecutableDocument, FragmentSpread, InlineFragment, TypeCondition};
use crate::parser::types::{
ExecutableDefinition, ExecutableDocument, FragmentSpread, InlineFragment, TypeCondition,
};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Positioned;
use std::collections::HashMap;

View File

@ -12,7 +12,11 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
ctx: &mut VisitorContext<'a>,
directive: &'a Positioned<Directive>,
) {
if let Some(schema_directive) = ctx.registry.directives.get(directive.node.name.node.as_str()) {
if let Some(schema_directive) = ctx
.registry
.directives
.get(directive.node.name.node.as_str())
{
for arg in schema_directive.args.values() {
if MetaTypeName::create(&arg.ty).is_non_null()
&& arg.default_value.is_none()

View File

@ -1,4 +1,4 @@
use crate::parser::types::{Directive, Field, Value, Name};
use crate::parser::types::{Directive, Field, Name, Value};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Positioned;
use std::collections::HashSet;

View File

@ -1,5 +1,6 @@
use crate::parser::types::{
ExecutableDocument, FragmentDefinition, FragmentSpread, OperationDefinition, VariableDefinition, Value,
ExecutableDocument, FragmentDefinition, FragmentSpread, OperationDefinition, Value,
VariableDefinition,
};
use crate::registry::MetaTypeName;
use crate::validation::utils::Scope;

View File

@ -1,5 +1,5 @@
use crate::parser::types::{Value, ConstValue};
use crate::context::QueryPathNode;
use crate::parser::types::{ConstValue, Value};
use crate::{registry, QueryPathSegment, Variables};
use std::collections::HashSet;
@ -50,21 +50,18 @@ pub fn is_valid_input_value(
_ => is_valid_input_value(registry, variables, type_name, value, path_node),
},
registry::MetaTypeName::List(type_name) => match value {
ConstValue::List(elems) => {
elems
.iter()
.enumerate()
.find_map(|(idx, elem)| is_valid_input_value(
registry,
variables,
type_name,
elem,
QueryPathNode {
parent: Some(&path_node),
segment: QueryPathSegment::Index(idx),
}
))
}
ConstValue::List(elems) => elems.iter().enumerate().find_map(|(idx, elem)| {
is_valid_input_value(
registry,
variables,
type_name,
elem,
QueryPathNode {
parent: Some(&path_node),
segment: QueryPathSegment::Index(idx),
},
)
}),
_ => is_valid_input_value(registry, variables, type_name, value, path_node),
},
registry::MetaTypeName::Named(type_name) => {
@ -83,15 +80,18 @@ pub fn is_valid_input_value(
))
}
}
registry::MetaType::Enum { enum_values, name: enum_name, .. } => match value {
registry::MetaType::Enum {
enum_values,
name: enum_name,
..
} => match value {
ConstValue::Enum(name) => {
if !enum_values.contains_key(name.as_str()) {
Some(valid_error(
&path_node,
format!(
"enumeration type \"{}\" does not contain the value \"{}\"",
enum_name,
name
enum_name, name
),
))
} else {
@ -103,7 +103,11 @@ pub fn is_valid_input_value(
format!("expected type \"{}\"", type_name),
)),
},
registry::MetaType::InputObject { input_fields, name: object_name, .. } => match value {
registry::MetaType::InputObject {
input_fields,
name: object_name,
..
} => match value {
ConstValue::Object(values) => {
let mut input_names = values
.keys()
@ -141,20 +145,19 @@ pub fn is_valid_input_value(
&& field.default_value.is_none()
{
return Some(valid_error(
&path_node,
format!(
"field \"{}\" of type \"{}\" is required but not provided",
field.name,
object_name,
),
));
&path_node,
format!(
"field \"{}\" of type \"{}\" is required but not provided",
field.name, object_name,
),
));
}
}
if let Some(name) = input_names.iter().next() {
return Some(valid_error(
&path_node,
format!("unknown field \"{}\" of type \"{}\"", name, object_name)
format!("unknown field \"{}\" of type \"{}\"", name, object_name),
));
}

View File

@ -1,7 +1,8 @@
use crate::error::RuleError;
use crate::parser::types::{
ExecutableDefinition, Directive, ExecutableDocument, Field, FragmentDefinition, FragmentSpread, InlineFragment,
OperationDefinition, OperationType, Selection, SelectionSet, TypeCondition, VariableDefinition, Value, Name
Directive, ExecutableDefinition, ExecutableDocument, Field, FragmentDefinition, FragmentSpread,
InlineFragment, Name, OperationDefinition, OperationType, Selection, SelectionSet,
TypeCondition, Value, VariableDefinition,
};
use crate::registry::{self, MetaType, MetaTypeName};
use crate::{Pos, Positioned, Variables};
@ -32,7 +33,9 @@ impl<'a> VisitorContext<'a> {
.definitions
.iter()
.filter_map(|d| match &d {
ExecutableDefinition::Fragment(fragment) => Some((&*fragment.node.name.node, fragment)),
ExecutableDefinition::Fragment(fragment) => {
Some((&*fragment.node.name.node, fragment))
}
_ => None,
})
.collect(),
@ -446,7 +449,11 @@ where
}
}
pub fn visit<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut VisitorContext<'a>, doc: &'a ExecutableDocument) {
pub fn visit<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
doc: &'a ExecutableDocument,
) {
v.enter_document(ctx, doc);
visit_definitions(v, ctx, doc);
v.exit_document(ctx, doc);

View File

@ -132,7 +132,8 @@ pub async fn test_inputobject_flatten_recursive() {
"a": 10,
"b": 20,
"c": 30,
})).unwrap()
}))
.unwrap()
))
.unwrap(),
MyInputObject {
@ -157,7 +158,8 @@ pub async fn test_inputobject_flatten_recursive() {
"a": 10,
"b": 20,
"c": 30,
})).unwrap()
}))
.unwrap()
);
struct Query;
@ -265,7 +267,8 @@ pub async fn test_inputobject_flatten_multiple() {
"a": 10,
"b": 20,
"c": 30,
})).unwrap()
}))
.unwrap()
))
.unwrap(),
ABC {
@ -286,6 +289,7 @@ pub async fn test_inputobject_flatten_multiple() {
"a": 10,
"b": 20,
"c": 30,
})).unwrap()
}))
.unwrap()
);
}

View File

@ -2,8 +2,8 @@ use async_graphql::validators::{
Email, IntEqual, IntGreaterThan, IntLessThan, IntNonZero, IntRange, ListMaxLength,
ListMinLength, StringMaxLength, StringMinLength, MAC,
};
use async_graphql_parser::types::Name;
use async_graphql::*;
use async_graphql_parser::types::Name;
#[async_std::test]
pub async fn test_input_validator_string_min_length() {
@ -1626,9 +1626,10 @@ pub async fn test_input_validator_variable() {
let validator_length = 6;
for case in &test_cases {
let mut variables = Variables::default();
variables
.0
.insert(Name::new("id".to_owned()).unwrap(), Value::String(case.to_string()));
variables.0.insert(
Name::new("id".to_owned()).unwrap(),
Value::String(case.to_string()),
);
let field_query = "query($id: String!) {fieldParameter(id: $id)}";
let object_query = "query($id: String!) {inputObject(input: {id: $id})}";

View File

@ -24,12 +24,10 @@ pub async fn test_variables() {
}
"#,
)
.variables(
Variables::parse_from_json(serde_json::json!({
"intVal": 10,
"intListVal": [1, 2, 3, 4, 5],
}))
);
.variables(Variables::parse_from_json(serde_json::json!({
"intVal": 10,
"intListVal": [1, 2, 3, 4, 5],
})));
let resp = query.execute(&schema).await.unwrap();
assert_eq!(
resp.data,
@ -118,11 +116,9 @@ pub async fn test_variable_null() {
}
"#,
)
.variables(
Variables::parse_from_json(serde_json::json!({
"intVal": null,
}))
);
.variables(Variables::parse_from_json(serde_json::json!({
"intVal": null,
})));
let resp = query.execute(&schema).await.unwrap();
assert_eq!(
resp.data,
@ -170,11 +166,9 @@ pub async fn test_variable_in_input_object() {
test(input: {value: $value })
}"#;
let resp = QueryBuilder::new(query)
.variables(
Variables::parse_from_json(serde_json::json!({
"value": 10,
}))
)
.variables(Variables::parse_from_json(serde_json::json!({
"value": 10,
})))
.execute(&schema)
.await
.unwrap();
@ -193,11 +187,9 @@ pub async fn test_variable_in_input_object() {
test2(input: [{value: $value }, {value: $value }])
}"#;
let resp = QueryBuilder::new(query)
.variables(
Variables::parse_from_json(serde_json::json!({
"value": 3,
}))
)
.variables(Variables::parse_from_json(serde_json::json!({
"value": 3,
})))
.execute(&schema)
.await
.unwrap();
@ -216,11 +208,9 @@ pub async fn test_variable_in_input_object() {
test(input: {value: $value })
}"#;
let resp = QueryBuilder::new(query)
.variables(
Variables::parse_from_json(serde_json::json!({
"value": 10,
}))
)
.variables(Variables::parse_from_json(serde_json::json!({
"value": 10,
})))
.execute(&schema)
.await
.unwrap();