Avoid boxing in MultiVisitor
This commit is contained in:
parent
d15f9bd162
commit
dc140a1ea0
4 changed files with 51 additions and 46 deletions
|
@ -14,7 +14,7 @@ pub use self::traits::Visitor;
|
||||||
pub use self::visitor::visit;
|
pub use self::visitor::visit;
|
||||||
pub use self::context::{RuleError, ValidatorContext};
|
pub use self::context::{RuleError, ValidatorContext};
|
||||||
pub use self::rules::visit_all_rules;
|
pub use self::rules::visit_all_rules;
|
||||||
pub use self::multi_visitor::MultiVisitor;
|
pub use self::multi_visitor::{MultiVisitor, MultiVisitorNil};
|
||||||
pub use self::input_value::validate_input_values;
|
pub use self::input_value::validate_input_values;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -4,26 +4,32 @@ use parser::Spanning;
|
||||||
use validation::{ValidatorContext, Visitor};
|
use validation::{ValidatorContext, Visitor};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct MultiVisitor<'a> {
|
pub trait MultiVisitor<'a> {
|
||||||
visitors: Vec<Box<Visitor<'a> + 'a>>
|
fn visit_all<F: FnMut(&mut Visitor<'a>) -> ()>(&mut self, f: F);
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> MultiVisitor<'a> {
|
fn with<V: Visitor<'a>>(self, visitor: V) -> MultiVisitorCons<V, Self> where Self: Sized {
|
||||||
#[doc(hidden)]
|
MultiVisitorCons(visitor, self)
|
||||||
pub fn new(visitors: Vec<Box<Visitor<'a> + 'a>>) -> MultiVisitor<'a> {
|
|
||||||
MultiVisitor {
|
|
||||||
visitors: visitors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_all<F: FnMut(&mut Box<Visitor<'a> + 'a>) -> ()>(&mut self, mut f: F) {
|
|
||||||
for mut v in &mut self.visitors {
|
|
||||||
f(v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Visitor<'a> for MultiVisitor<'a> {
|
#[doc(hidden)]
|
||||||
|
pub struct MultiVisitorNil;
|
||||||
|
|
||||||
|
impl<'a> MultiVisitor<'a> for MultiVisitorNil {
|
||||||
|
fn visit_all<F: FnMut(&mut Visitor<'a>) -> ()>(&mut self, _: F) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub struct MultiVisitorCons<A, B>(A, B);
|
||||||
|
|
||||||
|
impl<'a, A: Visitor<'a>, B: MultiVisitor<'a>> MultiVisitor<'a> for MultiVisitorCons<A, B> {
|
||||||
|
fn visit_all<F: FnMut(&mut Visitor<'a>) -> ()>(&mut self, mut f: F) {
|
||||||
|
f(&mut self.0);
|
||||||
|
self.1.visit_all(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, M> Visitor<'a> for M where M: MultiVisitor<'a> {
|
||||||
fn enter_document(&mut self, ctx: &mut ValidatorContext<'a>, doc: &'a Document) {
|
fn enter_document(&mut self, ctx: &mut ValidatorContext<'a>, doc: &'a Document) {
|
||||||
self.visit_all(|v| v.enter_document(ctx, doc));
|
self.visit_all(|v| v.enter_document(ctx, doc));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,36 +24,35 @@ mod variables_are_input_types;
|
||||||
mod variables_in_allowed_position;
|
mod variables_in_allowed_position;
|
||||||
|
|
||||||
use ast::Document;
|
use ast::Document;
|
||||||
use validation::{ValidatorContext, MultiVisitor, visit};
|
use validation::{ValidatorContext, MultiVisitor, MultiVisitorNil, visit};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn visit_all_rules<'a>(ctx: &mut ValidatorContext<'a>, doc: &'a Document) {
|
pub fn visit_all_rules<'a>(ctx: &mut ValidatorContext<'a>, doc: &'a Document) {
|
||||||
let mut mv = MultiVisitor::new(vec![
|
let mut mv = MultiVisitorNil
|
||||||
Box::new(self::arguments_of_correct_type::factory()),
|
.with(self::arguments_of_correct_type::factory())
|
||||||
Box::new(self::default_values_of_correct_type::factory()),
|
.with(self::default_values_of_correct_type::factory())
|
||||||
Box::new(self::fields_on_correct_type::factory()),
|
.with(self::fields_on_correct_type::factory())
|
||||||
Box::new(self::fragments_on_composite_types::factory()),
|
.with(self::fragments_on_composite_types::factory())
|
||||||
Box::new(self::known_argument_names::factory()),
|
.with(self::known_argument_names::factory())
|
||||||
Box::new(self::known_directives::factory()),
|
.with(self::known_directives::factory())
|
||||||
Box::new(self::known_fragment_names::factory()),
|
.with(self::known_fragment_names::factory())
|
||||||
Box::new(self::known_type_names::factory()),
|
.with(self::known_type_names::factory())
|
||||||
Box::new(self::lone_anonymous_operation::factory()),
|
.with(self::lone_anonymous_operation::factory())
|
||||||
Box::new(self::no_fragment_cycles::factory()),
|
.with(self::no_fragment_cycles::factory())
|
||||||
Box::new(self::no_undefined_variables::factory()),
|
.with(self::no_undefined_variables::factory())
|
||||||
Box::new(self::no_unused_fragments::factory()),
|
.with(self::no_unused_fragments::factory())
|
||||||
Box::new(self::no_unused_variables::factory()),
|
.with(self::no_unused_variables::factory())
|
||||||
Box::new(self::overlapping_fields_can_be_merged::factory()),
|
.with(self::overlapping_fields_can_be_merged::factory())
|
||||||
Box::new(self::possible_fragment_spreads::factory()),
|
.with(self::possible_fragment_spreads::factory())
|
||||||
Box::new(self::provided_non_null_arguments::factory()),
|
.with(self::provided_non_null_arguments::factory())
|
||||||
Box::new(self::scalar_leafs::factory()),
|
.with(self::scalar_leafs::factory())
|
||||||
Box::new(self::unique_argument_names::factory()),
|
.with(self::unique_argument_names::factory())
|
||||||
Box::new(self::unique_fragment_names::factory()),
|
.with(self::unique_fragment_names::factory())
|
||||||
Box::new(self::unique_input_field_names::factory()),
|
.with(self::unique_input_field_names::factory())
|
||||||
Box::new(self::unique_operation_names::factory()),
|
.with(self::unique_operation_names::factory())
|
||||||
Box::new(self::unique_variable_names::factory()),
|
.with(self::unique_variable_names::factory())
|
||||||
Box::new(self::variables_are_input_types::factory()),
|
.with(self::variables_are_input_types::factory())
|
||||||
Box::new(self::variables_in_allowed_position::factory()),
|
.with(self::variables_in_allowed_position::factory());
|
||||||
]);
|
|
||||||
|
|
||||||
visit(&mut mv, ctx, doc);
|
visit(&mut mv, ctx, doc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use executor::Registry;
|
||||||
use types::scalars::{EmptyMutation, ID};
|
use types::scalars::{EmptyMutation, ID};
|
||||||
use schema::model::{DirectiveType, DirectiveLocation, RootNode};
|
use schema::model::{DirectiveType, DirectiveLocation, RootNode};
|
||||||
use schema::meta::{EnumValue, MetaType};
|
use schema::meta::{EnumValue, MetaType};
|
||||||
use validation::{Visitor, RuleError, ValidatorContext, MultiVisitor, visit};
|
use validation::{Visitor, RuleError, ValidatorContext, MultiVisitor, MultiVisitorNil, visit};
|
||||||
|
|
||||||
struct Being;
|
struct Being;
|
||||||
struct Pet;
|
struct Pet;
|
||||||
|
@ -473,7 +473,7 @@ pub fn validate<'a, R, V, F>(r: R, q: &'a str, factory: F)
|
||||||
unsafe { ::std::mem::transmute(&root.schema) },
|
unsafe { ::std::mem::transmute(&root.schema) },
|
||||||
&doc);
|
&doc);
|
||||||
|
|
||||||
let mut mv = MultiVisitor::new(vec![ Box::new(factory()) ]);
|
let mut mv = MultiVisitorNil.with(factory());
|
||||||
visit(&mut mv, &mut ctx, unsafe { ::std::mem::transmute(&doc) });
|
visit(&mut mv, &mut ctx, unsafe { ::std::mem::transmute(&doc) });
|
||||||
|
|
||||||
ctx.into_errors()
|
ctx.into_errors()
|
||||||
|
|
Loading…
Reference in a new issue