bluejay_validator/executable/document/rules/
directives_are_defined.rs

1use crate::executable::{
2    document::{DirectiveError, Error, Rule, Visitor},
3    Cache,
4};
5use bluejay_core::definition::SchemaDefinition;
6use bluejay_core::executable::ExecutableDocument;
7use bluejay_core::Directive;
8
9pub struct DirectivesAreDefined<'a, E: ExecutableDocument, S: SchemaDefinition> {
10    schema_definition: &'a S,
11    errors: Vec<Error<'a, E, S>>,
12}
13
14impl<'a, E: ExecutableDocument + 'a, S: SchemaDefinition + 'a> DirectivesAreDefined<'a, E, S> {
15    fn visit_directive<
16        const CONST: bool,
17        F: Fn(DirectiveError<'a, CONST, E, S>) -> Error<'a, E, S>,
18    >(
19        &mut self,
20        directive: &'a <E as ExecutableDocument>::Directive<CONST>,
21        build_error: F,
22    ) {
23        if self
24            .schema_definition
25            .get_directive_definition(directive.name())
26            .is_none()
27        {
28            self.errors
29                .push(build_error(DirectiveError::DirectiveDoesNotExist {
30                    directive,
31                }));
32        }
33    }
34}
35
36impl<'a, E: ExecutableDocument + 'a, S: SchemaDefinition + 'a> Visitor<'a, E, S>
37    for DirectivesAreDefined<'a, E, S>
38{
39    fn new(_: &'a E, schema_definition: &'a S, _: &'a Cache<'a, E, S>) -> Self {
40        Self {
41            schema_definition,
42            errors: Vec::new(),
43        }
44    }
45
46    fn visit_variable_directive(
47        &mut self,
48        directive: &'a <E as ExecutableDocument>::Directive<false>,
49        _: bluejay_core::definition::DirectiveLocation,
50    ) {
51        self.visit_directive(directive, Error::InvalidVariableDirective)
52    }
53
54    fn visit_const_directive(
55        &mut self,
56        directive: &'a <E as ExecutableDocument>::Directive<true>,
57        _: bluejay_core::definition::DirectiveLocation,
58    ) {
59        self.visit_directive(directive, Error::InvalidConstDirective)
60    }
61}
62
63impl<'a, E: ExecutableDocument + 'a, S: SchemaDefinition + 'a> Rule<'a, E, S>
64    for DirectivesAreDefined<'a, E, S>
65{
66    type Error = Error<'a, E, S>;
67    type Errors = std::vec::IntoIter<Error<'a, E, S>>;
68
69    fn into_errors(self) -> Self::Errors {
70        self.errors.into_iter()
71    }
72}