Rustfmt
This commit is contained in:
parent
47259548c4
commit
04c898ef01
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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})}";
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue
Block a user