1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use crate::registry::TypeName;
use crate::validation::visitor::{Visitor, VisitorContext};
use graphql_parser::query::Field;
use graphql_parser::schema::Directive;

#[derive(Default)]
pub struct ProvidedNonNullArguments;

impl<'a> Visitor<'a> for ProvidedNonNullArguments {
    fn enter_directive(&mut self, ctx: &mut VisitorContext<'a>, directive: &'a Directive) {
        if let Some(schema_directive) = ctx.registry.directives.get(&directive.name) {
            for arg in schema_directive.args.values() {
                if TypeName::create(&arg.ty).is_non_null()
                    && arg.default_value.is_none()
                    && directive
                        .arguments
                        .iter()
                        .find(|(name, _)| name == arg.name)
                        .is_none()
                {
                    ctx.report_error(vec![directive.position],
                            format!(
                                "Directive \"@{}\" argument \"{}\" of type \"{}\" is required but not provided",
                                directive.name, arg.name, arg.ty
                            ));
                }
            }
        }
    }

    fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Field) {
        if let Some(parent_type) = ctx.parent_type() {
            if let Some(schema_field) = parent_type.field_by_name(&field.name) {
                for arg in schema_field.args.values() {
                    if TypeName::create(&arg.ty).is_non_null()
                        && arg.default_value.is_none()
                        && field
                            .arguments
                            .iter()
                            .find(|(name, _)| name == arg.name)
                            .is_none()
                    {
                        ctx.report_error(vec![field.position],
                             format!(
                                 r#"Field "{}" argument "{}" of type "{}" is required but not provided"#,
                                 field.name, arg.name, parent_type.name()
                             ));
                    }
                }
            }
        }
    }
}