async-graphql/src/validation/rules/arguments_of_correct_type.rs

72 lines
2.2 KiB
Rust
Raw Normal View History

2020-03-08 12:35:36 +00:00
use crate::registry::InputValue;
use crate::validation::context::ValidatorContext;
use crate::validation::utils::is_valid_input_value;
use crate::validation::visitor::Visitor;
use graphql_parser::query::Field;
use graphql_parser::schema::{Directive, Value};
use graphql_parser::Pos;
use std::collections::HashMap;
#[derive(Default)]
pub struct ArgumentsOfCorrectType<'a> {
2020-03-09 12:39:46 +00:00
current_args: Option<&'a HashMap<&'static str, InputValue>>,
2020-03-08 12:35:36 +00:00
}
impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
fn enter_directive(&mut self, ctx: &mut ValidatorContext<'a>, directive: &'a Directive) {
self.current_args = ctx
.registry
.directives
.get(&directive.name)
2020-03-09 12:39:46 +00:00
.map(|d| &d.args);
2020-03-08 12:35:36 +00:00
}
fn exit_directive(&mut self, _ctx: &mut ValidatorContext<'a>, _directive: &'a Directive) {
self.current_args = None;
}
2020-03-09 12:39:46 +00:00
fn enter_argument(
&mut self,
ctx: &mut ValidatorContext<'a>,
pos: Pos,
name: &str,
value: &'a Value,
) {
if let Some(arg) = self
2020-03-08 12:35:36 +00:00
.current_args
2020-03-09 12:39:46 +00:00
.and_then(|args| args.get(name).map(|input| input))
2020-03-08 12:35:36 +00:00
{
2020-03-22 01:34:32 +00:00
if let Some(validator) = &arg.validator {
2020-03-21 01:32:13 +00:00
if let Some(reason) = validator.is_valid(value) {
ctx.report_error(
vec![pos],
format!("Invalid value for argument \"{}\", {}", arg.name, reason,),
);
return;
}
}
2020-03-08 12:35:36 +00:00
if !is_valid_input_value(ctx.registry, &arg.ty, value) {
ctx.report_error(
vec![pos],
format!(
"Invalid value for argument \"{}\", expected type \"{}\"",
arg.name, arg.ty,
),
);
}
}
}
fn enter_field(&mut self, ctx: &mut ValidatorContext<'a>, field: &'a Field) {
self.current_args = ctx
.parent_type()
2020-03-09 04:08:50 +00:00
.and_then(|p| p.field_by_name(&field.name))
2020-03-09 12:39:46 +00:00
.map(|f| &f.args);
2020-03-08 12:35:36 +00:00
}
fn exit_field(&mut self, _ctx: &mut ValidatorContext<'a>, _field: &'a Field) {
self.current_args = None;
}
}