graphql-schema-validation 0.1.3

A spec compliant implementation of GraphQL SDL schema validation
Documentation
use super::{input_types::ValidateInputTypeResult, *};

pub(crate) fn validate_arguments<'a>(
    parent_field: (&str, &str),
    args: &'a [Positioned<ast::InputValueDefinition>],
    ctx: &mut Context<'a>,
) {
    {
        let arg_names = args.iter().map(|arg| arg.node.name.node.as_str());
        ctx.find_duplicates(arg_names, |ctx, _, duplicate| {
            let name = args[duplicate].node.name.node.as_str();
            ctx.push_error(miette::miette!(
                "Duplicate argument {name} in {}.{}",
                parent_field.0,
                parent_field.1
            ));
        });
    }

    for arg in args {
        let arg_name = &arg.node.name.node;

        if arg_name.starts_with("__") {
            let label = vec![miette::LabeledSpan::new_with_span(
                Some("here".to_owned()),
                miette::SourceSpan::new(ctx.miette_pos(arg.node.name.pos), arg.node.name.node.len().into()),
            )];
            ctx.push_error(miette::miette!(labels = label, "Argument names can't start with __"));
        }

        let type_name = super::extract_type_name(&arg.node.ty.node.base);
        let location = || format!("{}.{}({arg_name}:)", parent_field.0, parent_field.1);
        match super::input_types::validate_input_type(type_name, arg.node.ty.pos, ctx) {
            ValidateInputTypeResult::Ok => (),
            ValidateInputTypeResult::UnknownType => diagnostics::unknown_type(type_name, &location(), ctx),
            ValidateInputTypeResult::NotAnInputType => {
                diagnostics::output_type_in_input_position(type_name, &location(), ctx);
            }
        }

        if ctx.options.contains(crate::Options::DRAFT_VALIDATIONS) {
            let is_non_null_without_default = !arg.node.ty.node.nullable && arg.node.default_value.is_none();
            if is_non_null_without_default && arg.node.directives.iter().any(|dir| dir.node.name.node == "deprecated") {
                ctx.push_error(miette::miette!(
                    "Required argument {}.{}({}:) cannot be deprecated.",
                    parent_field.0,
                    parent_field.1,
                    arg.node.name.node,
                ));
            }
        }

        validate_directives(&arg.node.directives, ast::DirectiveLocation::ArgumentDefinition, ctx);
    }
}