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::context::{RuleError, ValidatorContext};
|
||||
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;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -4,26 +4,32 @@ use parser::Spanning;
|
|||
use validation::{ValidatorContext, Visitor};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct MultiVisitor<'a> {
|
||||
visitors: Vec<Box<Visitor<'a> + 'a>>
|
||||
}
|
||||
pub trait MultiVisitor<'a> {
|
||||
fn visit_all<F: FnMut(&mut Visitor<'a>) -> ()>(&mut self, f: F);
|
||||
|
||||
impl<'a> MultiVisitor<'a> {
|
||||
#[doc(hidden)]
|
||||
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);
|
||||
}
|
||||
fn with<V: Visitor<'a>>(self, visitor: V) -> MultiVisitorCons<V, Self> where Self: Sized {
|
||||
MultiVisitorCons(visitor, self)
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
self.visit_all(|v| v.enter_document(ctx, doc));
|
||||
}
|
||||
|
|
|
@ -24,36 +24,35 @@ mod variables_are_input_types;
|
|||
mod variables_in_allowed_position;
|
||||
|
||||
use ast::Document;
|
||||
use validation::{ValidatorContext, MultiVisitor, visit};
|
||||
use validation::{ValidatorContext, MultiVisitor, MultiVisitorNil, visit};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn visit_all_rules<'a>(ctx: &mut ValidatorContext<'a>, doc: &'a Document) {
|
||||
let mut mv = MultiVisitor::new(vec![
|
||||
Box::new(self::arguments_of_correct_type::factory()),
|
||||
Box::new(self::default_values_of_correct_type::factory()),
|
||||
Box::new(self::fields_on_correct_type::factory()),
|
||||
Box::new(self::fragments_on_composite_types::factory()),
|
||||
Box::new(self::known_argument_names::factory()),
|
||||
Box::new(self::known_directives::factory()),
|
||||
Box::new(self::known_fragment_names::factory()),
|
||||
Box::new(self::known_type_names::factory()),
|
||||
Box::new(self::lone_anonymous_operation::factory()),
|
||||
Box::new(self::no_fragment_cycles::factory()),
|
||||
Box::new(self::no_undefined_variables::factory()),
|
||||
Box::new(self::no_unused_fragments::factory()),
|
||||
Box::new(self::no_unused_variables::factory()),
|
||||
Box::new(self::overlapping_fields_can_be_merged::factory()),
|
||||
Box::new(self::possible_fragment_spreads::factory()),
|
||||
Box::new(self::provided_non_null_arguments::factory()),
|
||||
Box::new(self::scalar_leafs::factory()),
|
||||
Box::new(self::unique_argument_names::factory()),
|
||||
Box::new(self::unique_fragment_names::factory()),
|
||||
Box::new(self::unique_input_field_names::factory()),
|
||||
Box::new(self::unique_operation_names::factory()),
|
||||
Box::new(self::unique_variable_names::factory()),
|
||||
Box::new(self::variables_are_input_types::factory()),
|
||||
Box::new(self::variables_in_allowed_position::factory()),
|
||||
]);
|
||||
let mut mv = MultiVisitorNil
|
||||
.with(self::arguments_of_correct_type::factory())
|
||||
.with(self::default_values_of_correct_type::factory())
|
||||
.with(self::fields_on_correct_type::factory())
|
||||
.with(self::fragments_on_composite_types::factory())
|
||||
.with(self::known_argument_names::factory())
|
||||
.with(self::known_directives::factory())
|
||||
.with(self::known_fragment_names::factory())
|
||||
.with(self::known_type_names::factory())
|
||||
.with(self::lone_anonymous_operation::factory())
|
||||
.with(self::no_fragment_cycles::factory())
|
||||
.with(self::no_undefined_variables::factory())
|
||||
.with(self::no_unused_fragments::factory())
|
||||
.with(self::no_unused_variables::factory())
|
||||
.with(self::overlapping_fields_can_be_merged::factory())
|
||||
.with(self::possible_fragment_spreads::factory())
|
||||
.with(self::provided_non_null_arguments::factory())
|
||||
.with(self::scalar_leafs::factory())
|
||||
.with(self::unique_argument_names::factory())
|
||||
.with(self::unique_fragment_names::factory())
|
||||
.with(self::unique_input_field_names::factory())
|
||||
.with(self::unique_operation_names::factory())
|
||||
.with(self::unique_variable_names::factory())
|
||||
.with(self::variables_are_input_types::factory())
|
||||
.with(self::variables_in_allowed_position::factory());
|
||||
|
||||
visit(&mut mv, ctx, doc);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use executor::Registry;
|
|||
use types::scalars::{EmptyMutation, ID};
|
||||
use schema::model::{DirectiveType, DirectiveLocation, RootNode};
|
||||
use schema::meta::{EnumValue, MetaType};
|
||||
use validation::{Visitor, RuleError, ValidatorContext, MultiVisitor, visit};
|
||||
use validation::{Visitor, RuleError, ValidatorContext, MultiVisitor, MultiVisitorNil, visit};
|
||||
|
||||
struct Being;
|
||||
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) },
|
||||
&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) });
|
||||
|
||||
ctx.into_errors()
|
||||
|
|
Loading…
Reference in a new issue