Avoid copying Span
when evaluating validation rules (#1242)
This commit is contained in:
parent
f213d5193c
commit
8a69e14c8b
8 changed files with 115 additions and 70 deletions
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
parser::Spanning,
|
parser::Spanning,
|
||||||
validation::{ValidatorContext, Visitor},
|
validation::{ValidatorContext, Visitor},
|
||||||
value::ScalarValue,
|
value::ScalarValue,
|
||||||
|
Span,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -177,38 +178,46 @@ where
|
||||||
self.1.exit_inline_fragment(ctx, f);
|
self.1.exit_inline_fragment(ctx, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_null_value(&mut self, ctx: &mut ValidatorContext<'a, S>, n: Spanning<()>) {
|
fn enter_null_value(&mut self, ctx: &mut ValidatorContext<'a, S>, n: SpannedInput<'a, ()>) {
|
||||||
self.0.enter_null_value(ctx, n);
|
self.0.enter_null_value(ctx, n);
|
||||||
self.1.enter_null_value(ctx, n);
|
self.1.enter_null_value(ctx, n);
|
||||||
}
|
}
|
||||||
fn exit_null_value(&mut self, ctx: &mut ValidatorContext<'a, S>, n: Spanning<()>) {
|
fn exit_null_value(&mut self, ctx: &mut ValidatorContext<'a, S>, n: SpannedInput<'a, ()>) {
|
||||||
self.0.exit_null_value(ctx, n);
|
self.0.exit_null_value(ctx, n);
|
||||||
self.1.exit_null_value(ctx, n);
|
self.1.exit_null_value(ctx, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_scalar_value(&mut self, ctx: &mut ValidatorContext<'a, S>, n: Spanning<&'a S>) {
|
fn enter_scalar_value(&mut self, ctx: &mut ValidatorContext<'a, S>, n: SpannedInput<'a, S>) {
|
||||||
self.0.enter_scalar_value(ctx, n);
|
self.0.enter_scalar_value(ctx, n);
|
||||||
self.1.enter_scalar_value(ctx, n);
|
self.1.enter_scalar_value(ctx, n);
|
||||||
}
|
}
|
||||||
fn exit_scalar_value(&mut self, ctx: &mut ValidatorContext<'a, S>, n: Spanning<&'a S>) {
|
fn exit_scalar_value(&mut self, ctx: &mut ValidatorContext<'a, S>, n: SpannedInput<'a, S>) {
|
||||||
self.0.exit_scalar_value(ctx, n);
|
self.0.exit_scalar_value(ctx, n);
|
||||||
self.1.exit_scalar_value(ctx, n);
|
self.1.exit_scalar_value(ctx, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_enum_value(&mut self, ctx: &mut ValidatorContext<'a, S>, s: Spanning<&'a String>) {
|
fn enter_enum_value(&mut self, ctx: &mut ValidatorContext<'a, S>, s: SpannedInput<'a, String>) {
|
||||||
self.0.enter_enum_value(ctx, s);
|
self.0.enter_enum_value(ctx, s);
|
||||||
self.1.enter_enum_value(ctx, s);
|
self.1.enter_enum_value(ctx, s);
|
||||||
}
|
}
|
||||||
fn exit_enum_value(&mut self, ctx: &mut ValidatorContext<'a, S>, s: Spanning<&'a String>) {
|
fn exit_enum_value(&mut self, ctx: &mut ValidatorContext<'a, S>, s: SpannedInput<'a, String>) {
|
||||||
self.0.exit_enum_value(ctx, s);
|
self.0.exit_enum_value(ctx, s);
|
||||||
self.1.exit_enum_value(ctx, s);
|
self.1.exit_enum_value(ctx, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_variable_value(&mut self, ctx: &mut ValidatorContext<'a, S>, s: Spanning<&'a String>) {
|
fn enter_variable_value(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut ValidatorContext<'a, S>,
|
||||||
|
s: SpannedInput<'a, String>,
|
||||||
|
) {
|
||||||
self.0.enter_variable_value(ctx, s);
|
self.0.enter_variable_value(ctx, s);
|
||||||
self.1.enter_variable_value(ctx, s);
|
self.1.enter_variable_value(ctx, s);
|
||||||
}
|
}
|
||||||
fn exit_variable_value(&mut self, ctx: &mut ValidatorContext<'a, S>, s: Spanning<&'a String>) {
|
fn exit_variable_value(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut ValidatorContext<'a, S>,
|
||||||
|
s: SpannedInput<'a, String>,
|
||||||
|
) {
|
||||||
self.0.exit_variable_value(ctx, s);
|
self.0.exit_variable_value(ctx, s);
|
||||||
self.1.exit_variable_value(ctx, s);
|
self.1.exit_variable_value(ctx, s);
|
||||||
}
|
}
|
||||||
|
@ -216,7 +225,7 @@ where
|
||||||
fn enter_list_value(
|
fn enter_list_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut ValidatorContext<'a, S>,
|
ctx: &mut ValidatorContext<'a, S>,
|
||||||
l: Spanning<&'a Vec<Spanning<InputValue<S>>>>,
|
l: SpannedInput<'a, Vec<Spanning<InputValue<S>>>>,
|
||||||
) {
|
) {
|
||||||
self.0.enter_list_value(ctx, l);
|
self.0.enter_list_value(ctx, l);
|
||||||
self.1.enter_list_value(ctx, l);
|
self.1.enter_list_value(ctx, l);
|
||||||
|
@ -224,7 +233,7 @@ where
|
||||||
fn exit_list_value(
|
fn exit_list_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut ValidatorContext<'a, S>,
|
ctx: &mut ValidatorContext<'a, S>,
|
||||||
l: Spanning<&'a Vec<Spanning<InputValue<S>>>>,
|
l: SpannedInput<'a, Vec<Spanning<InputValue<S>>>>,
|
||||||
) {
|
) {
|
||||||
self.0.exit_list_value(ctx, l);
|
self.0.exit_list_value(ctx, l);
|
||||||
self.1.exit_list_value(ctx, l);
|
self.1.exit_list_value(ctx, l);
|
||||||
|
@ -242,7 +251,7 @@ where
|
||||||
fn enter_object_field(
|
fn enter_object_field(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut ValidatorContext<'a, S>,
|
ctx: &mut ValidatorContext<'a, S>,
|
||||||
f: &'a (Spanning<String>, Spanning<InputValue<S>>),
|
f: (SpannedInput<'a, String>, SpannedInput<'a, InputValue<S>>),
|
||||||
) {
|
) {
|
||||||
self.0.enter_object_field(ctx, f);
|
self.0.enter_object_field(ctx, f);
|
||||||
self.1.enter_object_field(ctx, f);
|
self.1.enter_object_field(ctx, f);
|
||||||
|
@ -250,11 +259,12 @@ where
|
||||||
fn exit_object_field(
|
fn exit_object_field(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut ValidatorContext<'a, S>,
|
ctx: &mut ValidatorContext<'a, S>,
|
||||||
f: &'a (Spanning<String>, Spanning<InputValue<S>>),
|
f: (SpannedInput<'a, String>, SpannedInput<'a, InputValue<S>>),
|
||||||
) {
|
) {
|
||||||
self.0.exit_object_field(ctx, f);
|
self.0.exit_object_field(ctx, f);
|
||||||
self.1.exit_object_field(ctx, f);
|
self.1.exit_object_field(ctx, f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SpannedObject<'a, S> = Spanning<&'a Vec<(Spanning<String>, Spanning<InputValue<S>>)>>;
|
type SpannedInput<'a, T> = Spanning<&'a T, &'a Span>;
|
||||||
|
type SpannedObject<'a, S> = SpannedInput<'a, Vec<(Spanning<String>, Spanning<InputValue<S>>)>>;
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::{
|
||||||
parser::Spanning,
|
parser::Spanning,
|
||||||
validation::{RuleError, ValidatorContext, Visitor},
|
validation::{RuleError, ValidatorContext, Visitor},
|
||||||
value::ScalarValue,
|
value::ScalarValue,
|
||||||
|
Span,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn factory<'a>() -> NoFragmentCycles<'a> {
|
pub fn factory<'a>() -> NoFragmentCycles<'a> {
|
||||||
|
@ -15,9 +16,11 @@ pub fn factory<'a>() -> NoFragmentCycles<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BorrowedSpanning<'a, T> = Spanning<&'a T, &'a Span>;
|
||||||
|
|
||||||
pub struct NoFragmentCycles<'a> {
|
pub struct NoFragmentCycles<'a> {
|
||||||
current_fragment: Option<&'a str>,
|
current_fragment: Option<&'a str>,
|
||||||
spreads: HashMap<&'a str, Vec<Spanning<&'a str>>>,
|
spreads: HashMap<&'a str, Vec<BorrowedSpanning<'a, str>>>,
|
||||||
fragment_order: Vec<&'a str>,
|
fragment_order: Vec<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,16 +76,23 @@ where
|
||||||
self.spreads
|
self.spreads
|
||||||
.entry(current_fragment)
|
.entry(current_fragment)
|
||||||
.or_default()
|
.or_default()
|
||||||
.push(Spanning::new(spread.span, spread.item.name.item));
|
.push(BorrowedSpanning {
|
||||||
|
item: spread.item.name.item,
|
||||||
|
span: &spread.span,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type CycleDetectorState<'a> = (&'a str, Vec<&'a Spanning<&'a str>>, HashMap<&'a str, usize>);
|
type CycleDetectorState<'a> = (
|
||||||
|
&'a str,
|
||||||
|
Vec<&'a BorrowedSpanning<'a, str>>,
|
||||||
|
HashMap<&'a str, usize>,
|
||||||
|
);
|
||||||
|
|
||||||
struct CycleDetector<'a> {
|
struct CycleDetector<'a> {
|
||||||
visited: HashSet<&'a str>,
|
visited: HashSet<&'a str>,
|
||||||
spreads: &'a HashMap<&'a str, Vec<Spanning<&'a str>>>,
|
spreads: &'a HashMap<&'a str, Vec<BorrowedSpanning<'a, str>>>,
|
||||||
errors: Vec<RuleError>,
|
errors: Vec<RuleError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +113,7 @@ impl<'a> CycleDetector<'a> {
|
||||||
fn detect_from_inner(
|
fn detect_from_inner(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: &'a str,
|
from: &'a str,
|
||||||
path: Vec<&'a Spanning<&'a str>>,
|
path: Vec<&'a BorrowedSpanning<'a, str>>,
|
||||||
mut path_indices: HashMap<&'a str, usize>,
|
mut path_indices: HashMap<&'a str, usize>,
|
||||||
) -> Vec<CycleDetectorState<'a>> {
|
) -> Vec<CycleDetectorState<'a>> {
|
||||||
self.visited.insert(from);
|
self.visited.insert(from);
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::{
|
||||||
parser::{SourcePosition, Spanning},
|
parser::{SourcePosition, Spanning},
|
||||||
validation::{RuleError, ValidatorContext, Visitor},
|
validation::{RuleError, ValidatorContext, Visitor},
|
||||||
value::ScalarValue,
|
value::ScalarValue,
|
||||||
|
Span,
|
||||||
};
|
};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
@ -21,9 +22,11 @@ pub fn factory<'a>() -> NoUndefinedVariables<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BorrowedSpanning<'a, T> = Spanning<&'a T, &'a Span>;
|
||||||
|
|
||||||
pub struct NoUndefinedVariables<'a> {
|
pub struct NoUndefinedVariables<'a> {
|
||||||
defined_variables: HashMap<Option<&'a str>, (SourcePosition, HashSet<&'a str>)>,
|
defined_variables: HashMap<Option<&'a str>, (SourcePosition, HashSet<&'a str>)>,
|
||||||
used_variables: HashMap<Scope<'a>, Vec<Spanning<&'a str>>>,
|
used_variables: HashMap<Scope<'a>, Vec<BorrowedSpanning<'a, str>>>,
|
||||||
current_scope: Option<Scope<'a>>,
|
current_scope: Option<Scope<'a>>,
|
||||||
spreads: HashMap<Scope<'a>, Vec<&'a str>>,
|
spreads: HashMap<Scope<'a>, Vec<&'a str>>,
|
||||||
}
|
}
|
||||||
|
@ -33,7 +36,7 @@ impl<'a> NoUndefinedVariables<'a> {
|
||||||
&'a self,
|
&'a self,
|
||||||
scope: &Scope<'a>,
|
scope: &Scope<'a>,
|
||||||
defined: &HashSet<&'a str>,
|
defined: &HashSet<&'a str>,
|
||||||
unused: &mut Vec<&'a Spanning<&'a str>>,
|
unused: &mut Vec<BorrowedSpanning<'a, str>>,
|
||||||
visited: &mut HashSet<Scope<'a>>,
|
visited: &mut HashSet<Scope<'a>>,
|
||||||
) {
|
) {
|
||||||
let mut to_visit = Vec::new();
|
let mut to_visit = Vec::new();
|
||||||
|
@ -59,7 +62,7 @@ impl<'a> NoUndefinedVariables<'a> {
|
||||||
&'a self,
|
&'a self,
|
||||||
scope: &Scope<'a>,
|
scope: &Scope<'a>,
|
||||||
defined: &HashSet<&'a str>,
|
defined: &HashSet<&'a str>,
|
||||||
unused: &mut Vec<&'a Spanning<&'a str>>,
|
unused: &mut Vec<BorrowedSpanning<'a, str>>,
|
||||||
visited: &mut HashSet<Scope<'a>>,
|
visited: &mut HashSet<Scope<'a>>,
|
||||||
) -> Option<&'a Vec<&'a str>> {
|
) -> Option<&'a Vec<&'a str>> {
|
||||||
if visited.contains(scope) {
|
if visited.contains(scope) {
|
||||||
|
@ -71,7 +74,7 @@ impl<'a> NoUndefinedVariables<'a> {
|
||||||
if let Some(used_vars) = self.used_variables.get(scope) {
|
if let Some(used_vars) = self.used_variables.get(scope) {
|
||||||
for var in used_vars {
|
for var in used_vars {
|
||||||
if !defined.contains(&var.item) {
|
if !defined.contains(&var.item) {
|
||||||
unused.push(var);
|
unused.push(*var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +167,10 @@ where
|
||||||
.item
|
.item
|
||||||
.referenced_variables()
|
.referenced_variables()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&var_name| Spanning::new(value.span, var_name))
|
.map(|&var_name| BorrowedSpanning {
|
||||||
|
span: &value.span,
|
||||||
|
item: var_name,
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::{
|
||||||
parser::Spanning,
|
parser::Spanning,
|
||||||
validation::{ValidatorContext, Visitor},
|
validation::{ValidatorContext, Visitor},
|
||||||
value::ScalarValue,
|
value::ScalarValue,
|
||||||
|
Span,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
@ -21,9 +22,11 @@ pub fn factory<'a>() -> NoUnusedFragments<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BorrowedSpanning<'a, T> = Spanning<&'a T, &'a Span>;
|
||||||
|
|
||||||
pub struct NoUnusedFragments<'a> {
|
pub struct NoUnusedFragments<'a> {
|
||||||
spreads: HashMap<Scope<'a>, Vec<&'a str>>,
|
spreads: HashMap<Scope<'a>, Vec<&'a str>>,
|
||||||
defined_fragments: HashSet<Spanning<&'a str>>,
|
defined_fragments: HashSet<BorrowedSpanning<'a, str>>,
|
||||||
current_scope: Option<Scope<'a>>,
|
current_scope: Option<Scope<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +103,10 @@ where
|
||||||
f: &'a Spanning<Fragment<S>>,
|
f: &'a Spanning<Fragment<S>>,
|
||||||
) {
|
) {
|
||||||
self.current_scope = Some(Scope::Fragment(f.item.name.item));
|
self.current_scope = Some(Scope::Fragment(f.item.name.item));
|
||||||
self.defined_fragments
|
self.defined_fragments.insert(BorrowedSpanning {
|
||||||
.insert(Spanning::new(f.span, f.item.name.item));
|
span: &f.span,
|
||||||
|
item: f.item.name.item,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_fragment_spread(
|
fn enter_fragment_spread(
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::{
|
||||||
parser::{SourcePosition, Spanning},
|
parser::{SourcePosition, Spanning},
|
||||||
validation::{ValidatorContext, Visitor},
|
validation::{ValidatorContext, Visitor},
|
||||||
value::ScalarValue,
|
value::ScalarValue,
|
||||||
|
Span,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct UniqueInputFieldNames<'a> {
|
pub struct UniqueInputFieldNames<'a> {
|
||||||
|
@ -32,13 +33,13 @@ where
|
||||||
fn enter_object_field(
|
fn enter_object_field(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut ValidatorContext<'a, S>,
|
ctx: &mut ValidatorContext<'a, S>,
|
||||||
(field_name, _): &'a (Spanning<String>, Spanning<InputValue<S>>),
|
(field_name, _): (SpannedInput<'a, String>, SpannedInput<InputValue<S>>),
|
||||||
) {
|
) {
|
||||||
if let Some(ref mut known_names) = self.known_name_stack.last_mut() {
|
if let Some(ref mut known_names) = self.known_name_stack.last_mut() {
|
||||||
match known_names.entry(&field_name.item) {
|
match known_names.entry(field_name.item) {
|
||||||
Entry::Occupied(e) => {
|
Entry::Occupied(e) => {
|
||||||
ctx.report_error(
|
ctx.report_error(
|
||||||
&error_message(&field_name.item),
|
&error_message(field_name.item),
|
||||||
&[*e.get(), field_name.span.start],
|
&[*e.get(), field_name.span.start],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +51,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SpannedObject<'a, S> = Spanning<&'a Vec<(Spanning<String>, Spanning<InputValue<S>>)>>;
|
type SpannedInput<'a, T> = Spanning<&'a T, &'a Span>;
|
||||||
|
type SpannedObject<'a, S> = SpannedInput<'a, Vec<(Spanning<String>, Spanning<InputValue<S>>)>>;
|
||||||
|
|
||||||
fn error_message(field_name: &str) -> String {
|
fn error_message(field_name: &str) -> String {
|
||||||
format!("There can only be one input field named \"{field_name}\"")
|
format!("There can only be one input field named \"{field_name}\"")
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
parser::Spanning,
|
parser::Spanning,
|
||||||
validation::{ValidatorContext, Visitor},
|
validation::{ValidatorContext, Visitor},
|
||||||
value::ScalarValue,
|
value::ScalarValue,
|
||||||
|
Span,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -28,7 +29,7 @@ pub fn factory<'a, S: fmt::Debug>() -> VariableInAllowedPosition<'a, S> {
|
||||||
|
|
||||||
pub struct VariableInAllowedPosition<'a, S: fmt::Debug + 'a> {
|
pub struct VariableInAllowedPosition<'a, S: fmt::Debug + 'a> {
|
||||||
spreads: HashMap<Scope<'a>, HashSet<&'a str>>,
|
spreads: HashMap<Scope<'a>, HashSet<&'a str>>,
|
||||||
variable_usages: HashMap<Scope<'a>, Vec<(Spanning<&'a String>, Type<'a>)>>,
|
variable_usages: HashMap<Scope<'a>, Vec<(SpannedInput<'a, String>, Type<'a>)>>,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
variable_defs: HashMap<Scope<'a>, Vec<&'a (Spanning<&'a str>, VariableDefinition<'a, S>)>>,
|
variable_defs: HashMap<Scope<'a>, Vec<&'a (Spanning<&'a str>, VariableDefinition<'a, S>)>>,
|
||||||
current_scope: Option<Scope<'a>>,
|
current_scope: Option<Scope<'a>>,
|
||||||
|
@ -160,7 +161,7 @@ where
|
||||||
fn enter_variable_value(
|
fn enter_variable_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut ValidatorContext<'a, S>,
|
ctx: &mut ValidatorContext<'a, S>,
|
||||||
var_name: Spanning<&'a String>,
|
var_name: SpannedInput<'a, String>,
|
||||||
) {
|
) {
|
||||||
if let (Some(scope), Some(input_type)) =
|
if let (Some(scope), Some(input_type)) =
|
||||||
(&self.current_scope, ctx.current_input_type_literal())
|
(&self.current_scope, ctx.current_input_type_literal())
|
||||||
|
@ -168,10 +169,7 @@ where
|
||||||
self.variable_usages
|
self.variable_usages
|
||||||
.entry(scope.clone())
|
.entry(scope.clone())
|
||||||
.or_default()
|
.or_default()
|
||||||
.push((
|
.push((var_name, input_type.clone()));
|
||||||
Spanning::new(var_name.span, var_name.item),
|
|
||||||
input_type.clone(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,6 +184,8 @@ fn error_message(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SpannedInput<'a, T> = Spanning<&'a T, &'a Span>;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{error_message, factory};
|
use super::{error_message, factory};
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
parser::Spanning,
|
parser::Spanning,
|
||||||
validation::ValidatorContext,
|
validation::ValidatorContext,
|
||||||
value::ScalarValue,
|
value::ScalarValue,
|
||||||
|
Span,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -103,28 +104,38 @@ where
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_null_value(&mut self, _: &mut ValidatorContext<'a, S>, _: Spanning<()>) {}
|
fn enter_null_value(&mut self, _: &mut ValidatorContext<'a, S>, _: SpannedInput<'a, ()>) {}
|
||||||
fn exit_null_value(&mut self, _: &mut ValidatorContext<'a, S>, _: Spanning<()>) {}
|
fn exit_null_value(&mut self, _: &mut ValidatorContext<'a, S>, _: SpannedInput<'a, ()>) {}
|
||||||
|
|
||||||
fn enter_scalar_value(&mut self, _: &mut ValidatorContext<'a, S>, _: Spanning<&'a S>) {}
|
fn enter_scalar_value(&mut self, _: &mut ValidatorContext<'a, S>, _: SpannedInput<'a, S>) {}
|
||||||
fn exit_scalar_value(&mut self, _: &mut ValidatorContext<'a, S>, _: Spanning<&'a S>) {}
|
fn exit_scalar_value(&mut self, _: &mut ValidatorContext<'a, S>, _: SpannedInput<'a, S>) {}
|
||||||
|
|
||||||
fn enter_enum_value(&mut self, _: &mut ValidatorContext<'a, S>, _: Spanning<&'a String>) {}
|
fn enter_enum_value(&mut self, _: &mut ValidatorContext<'a, S>, _: SpannedInput<'a, String>) {}
|
||||||
fn exit_enum_value(&mut self, _: &mut ValidatorContext<'a, S>, _: Spanning<&'a String>) {}
|
fn exit_enum_value(&mut self, _: &mut ValidatorContext<'a, S>, _: SpannedInput<'a, String>) {}
|
||||||
|
|
||||||
fn enter_variable_value(&mut self, _: &mut ValidatorContext<'a, S>, _: Spanning<&'a String>) {}
|
fn enter_variable_value(
|
||||||
fn exit_variable_value(&mut self, _: &mut ValidatorContext<'a, S>, _: Spanning<&'a String>) {}
|
&mut self,
|
||||||
|
_: &mut ValidatorContext<'a, S>,
|
||||||
|
_: SpannedInput<'a, String>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
fn exit_variable_value(
|
||||||
|
&mut self,
|
||||||
|
_: &mut ValidatorContext<'a, S>,
|
||||||
|
_: SpannedInput<'a, String>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
fn enter_list_value(
|
fn enter_list_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut ValidatorContext<'a, S>,
|
_: &mut ValidatorContext<'a, S>,
|
||||||
_: Spanning<&'a Vec<Spanning<InputValue<S>>>>,
|
_: SpannedInput<'a, Vec<Spanning<InputValue<S>>>>,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
fn exit_list_value(
|
fn exit_list_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut ValidatorContext<'a, S>,
|
_: &mut ValidatorContext<'a, S>,
|
||||||
_: Spanning<&'a Vec<Spanning<InputValue<S>>>>,
|
_: SpannedInput<'a, Vec<Spanning<InputValue<S>>>>,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,15 +145,16 @@ where
|
||||||
fn enter_object_field(
|
fn enter_object_field(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut ValidatorContext<'a, S>,
|
_: &mut ValidatorContext<'a, S>,
|
||||||
_: &'a (Spanning<String>, Spanning<InputValue<S>>),
|
_: (SpannedInput<'a, String>, SpannedInput<'a, InputValue<S>>),
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
fn exit_object_field(
|
fn exit_object_field(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut ValidatorContext<'a, S>,
|
_: &mut ValidatorContext<'a, S>,
|
||||||
_: &'a (Spanning<String>, Spanning<InputValue<S>>),
|
_: (SpannedInput<'a, String>, SpannedInput<'a, InputValue<S>>),
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SpannedObject<'a, S> = Spanning<&'a Vec<(Spanning<String>, Spanning<InputValue<S>>)>>;
|
type SpannedInput<'a, T> = Spanning<&'a T, &'a Span>;
|
||||||
|
type SpannedObject<'a, S> = SpannedInput<'a, Vec<(Spanning<String>, Spanning<InputValue<S>>)>>;
|
||||||
|
|
|
@ -328,7 +328,7 @@ fn visit_input_value<'a, S, V>(
|
||||||
|
|
||||||
match input_value.item {
|
match input_value.item {
|
||||||
InputValue::Object(ref fields) => {
|
InputValue::Object(ref fields) => {
|
||||||
for field in fields {
|
for (key, value) in fields {
|
||||||
let inner_type = ctx
|
let inner_type = ctx
|
||||||
.current_input_type_literal()
|
.current_input_type_literal()
|
||||||
.and_then(|t| match *t {
|
.and_then(|t| match *t {
|
||||||
|
@ -337,13 +337,13 @@ fn visit_input_value<'a, S, V>(
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.and_then(|ct| ct.input_field_by_name(&field.0.item))
|
.and_then(|ct| ct.input_field_by_name(&key.item))
|
||||||
.map(|f| &f.arg_type);
|
.map(|f| &f.arg_type);
|
||||||
|
|
||||||
ctx.with_pushed_input_type(inner_type, |ctx| {
|
ctx.with_pushed_input_type(inner_type, |ctx| {
|
||||||
v.enter_object_field(ctx, field);
|
v.enter_object_field(ctx, (key.as_ref(), value.as_ref()));
|
||||||
visit_input_value(v, ctx, &field.1);
|
visit_input_value(v, ctx, value);
|
||||||
v.exit_object_field(ctx, field);
|
v.exit_object_field(ctx, (key.as_ref(), value.as_ref()));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -377,15 +377,15 @@ fn enter_input_value<'a, S, V>(
|
||||||
{
|
{
|
||||||
use crate::InputValue::*;
|
use crate::InputValue::*;
|
||||||
|
|
||||||
let span = input_value.span;
|
let span = &input_value.span;
|
||||||
|
|
||||||
match input_value.item {
|
match &input_value.item {
|
||||||
Null => v.enter_null_value(ctx, Spanning::new(span, ())),
|
Null => v.enter_null_value(ctx, Spanning { span, item: &() }),
|
||||||
Scalar(ref s) => v.enter_scalar_value(ctx, Spanning::new(span, s)),
|
Scalar(item) => v.enter_scalar_value(ctx, Spanning { span, item }),
|
||||||
Enum(ref s) => v.enter_enum_value(ctx, Spanning::new(span, s)),
|
Enum(item) => v.enter_enum_value(ctx, Spanning { span, item }),
|
||||||
Variable(ref s) => v.enter_variable_value(ctx, Spanning::new(span, s)),
|
Variable(item) => v.enter_variable_value(ctx, Spanning { span, item }),
|
||||||
List(ref l) => v.enter_list_value(ctx, Spanning::new(span, l)),
|
List(item) => v.enter_list_value(ctx, Spanning { span, item }),
|
||||||
Object(ref o) => v.enter_object_value(ctx, Spanning::new(span, o)),
|
Object(item) => v.enter_object_value(ctx, Spanning { span, item }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,14 +399,14 @@ fn exit_input_value<'a, S, V>(
|
||||||
{
|
{
|
||||||
use crate::InputValue::*;
|
use crate::InputValue::*;
|
||||||
|
|
||||||
let span = input_value.span;
|
let span = &input_value.span;
|
||||||
|
|
||||||
match input_value.item {
|
match &input_value.item {
|
||||||
Null => v.exit_null_value(ctx, Spanning::new(span, ())),
|
Null => v.exit_null_value(ctx, Spanning { span, item: &() }),
|
||||||
Scalar(ref s) => v.exit_scalar_value(ctx, Spanning::new(span, s)),
|
Scalar(item) => v.exit_scalar_value(ctx, Spanning { span, item }),
|
||||||
Enum(ref s) => v.exit_enum_value(ctx, Spanning::new(span, s)),
|
Enum(item) => v.exit_enum_value(ctx, Spanning { span, item }),
|
||||||
Variable(ref s) => v.exit_variable_value(ctx, Spanning::new(span, s)),
|
Variable(item) => v.exit_variable_value(ctx, Spanning { span, item }),
|
||||||
List(ref l) => v.exit_list_value(ctx, Spanning::new(span, l)),
|
List(item) => v.exit_list_value(ctx, Spanning { span, item }),
|
||||||
Object(ref o) => v.exit_object_value(ctx, Spanning::new(span, o)),
|
Object(item) => v.exit_object_value(ctx, Spanning { span, item }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue