Update AND, OR, and MapErr logic. Update logic for object input

This commit is contained in:
Rodgers 2021-07-08 23:43:12 +07:00
parent 0ed7384cbf
commit 53c4945fc4
4 changed files with 78 additions and 59 deletions

View File

@ -68,7 +68,7 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
}
}
if let Some(reason) = value.and_then(|value| {
if let Some(e) = value.and_then(|value| {
is_valid_input_value(
ctx.registry,
&arg.ty,
@ -79,9 +79,10 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
},
)
}) {
ctx.report_error(
ctx.report_error_with_extensions(
vec![name.pos],
format!("Invalid value for argument {}", reason),
format!("Invalid value for argument {}", e.message),
e.extensions,
);
}
}

View File

@ -18,7 +18,7 @@ impl<'a> Visitor<'a> for DefaultValuesOfCorrectType {
"Argument \"{}\" has type \"{}\" and is not nullable, so it can't have a default value",
variable_definition.node.name, variable_definition.node.var_type,
));
} else if let Some(reason) = is_valid_input_value(
} else if let Some(e) = is_valid_input_value(
ctx.registry,
&variable_definition.node.var_type.to_string(),
&value.node,
@ -27,9 +27,10 @@ impl<'a> Visitor<'a> for DefaultValuesOfCorrectType {
segment: QueryPathSegment::Name(&variable_definition.node.name.node),
},
) {
ctx.report_error(
ctx.report_error_with_extensions(
vec![variable_definition.pos],
format!("Invalid default value for argument {}", reason),
format!("Invalid default value for argument {}", e.message),
e.extensions,
)
}
}

View File

@ -1,9 +1,11 @@
use std::collections::HashSet;
use crate::context::QueryPathNode;
use crate::{registry, QueryPathSegment};
use async_graphql_value::{ConstValue, Value};
use crate::context::QueryPathNode;
use crate::error::Error;
use crate::{registry, QueryPathSegment};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Scope<'a> {
Operation(Option<&'a str>),
@ -40,13 +42,12 @@ pub fn is_valid_input_value(
type_name: &str,
value: &ConstValue,
path_node: QueryPathNode,
) -> Option<String> {
) -> Option<Error> {
match registry::MetaTypeName::create(type_name) {
registry::MetaTypeName::NonNull(type_name) => match value {
ConstValue::Null => Some(valid_error(
&path_node,
format!("expected type \"{}\"", type_name),
)),
ConstValue::Null => {
Some(valid_error(&path_node, format!("expected type \"{}\"", type_name)).into())
}
_ => is_valid_input_value(registry, type_name, value, path_node),
},
registry::MetaTypeName::List(type_name) => match value {
@ -74,10 +75,10 @@ pub fn is_valid_input_value(
if is_valid(&value) {
None
} else {
Some(valid_error(
&path_node,
format!("expected type \"{}\"", type_name),
))
Some(
valid_error(&path_node, format!("expected type \"{}\"", type_name))
.into(),
)
}
}
registry::MetaType::Enum {
@ -87,34 +88,39 @@ pub fn is_valid_input_value(
} => match value {
ConstValue::Enum(name) => {
if !enum_values.contains_key(name.as_str()) {
Some(valid_error(
&path_node,
format!(
"enumeration type \"{}\" does not contain the value \"{}\"",
enum_name, name
),
))
Some(
valid_error(
&path_node,
format!(
"enumeration type \"{}\" does not contain the value \"{}\"",
enum_name, name
),
)
.into(),
)
} else {
None
}
}
ConstValue::String(name) => {
if !enum_values.contains_key(name.as_str()) {
Some(valid_error(
&path_node,
format!(
"enumeration type \"{}\" does not contain the value \"{}\"",
enum_name, name
),
))
Some(
valid_error(
&path_node,
format!(
"enumeration type \"{}\" does not contain the value \"{}\"",
enum_name, name
),
)
.into(),
)
} else {
None
}
}
_ => Some(valid_error(
&path_node,
format!("expected type \"{}\"", type_name),
)),
_ => Some(
valid_error(&path_node, format!("expected type \"{}\"", type_name)).into(),
),
},
registry::MetaType::InputObject {
input_fields,
@ -129,14 +135,15 @@ pub fn is_valid_input_value(
input_names.remove(field.name);
if let Some(value) = values.get(field.name) {
if let Some(validator) = &field.validator {
if let Err(reason) = validator.is_valid(value) {
return Some(valid_error(
if let Err(mut e) = validator.is_valid_with_extensions(value) {
e.message = valid_error(
&QueryPathNode {
parent: Some(&path_node),
segment: QueryPathSegment::Name(field.name),
},
reason,
));
e.message,
);
return Some(e);
}
}
@ -154,21 +161,30 @@ pub fn is_valid_input_value(
} else if registry::MetaTypeName::create(&field.ty).is_non_null()
&& field.default_value.is_none()
{
return Some(valid_error(
&path_node,
format!(
return Some(
valid_error(
&path_node,
format!(
"field \"{}\" of type \"{}\" is required but not provided",
field.name, object_name,
),
));
)
.into(),
);
}
}
if let Some(name) = input_names.iter().next() {
return Some(valid_error(
&path_node,
format!("unknown field \"{}\" of type \"{}\"", name, object_name),
));
return Some(
valid_error(
&path_node,
format!(
"unknown field \"{}\" of type \"{}\"",
name, object_name
),
)
.into(),
);
}
None

View File

@ -80,8 +80,7 @@ where
/// ```
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
// By default, use is_valid method to keep compatible with previous version
self.is_valid(value)?;
Ok(())
self.is_valid(value).map_err(|reason| Error::new(reason))
}
}
@ -98,7 +97,7 @@ pub trait InputValueValidatorExt: InputValueValidator + Sized {
}
/// Changes the error message
fn map_err<F: Fn(String) -> String>(self, f: F) -> MapErr<Self, F> {
fn map_err<F: Fn(Error) -> Error>(self, f: F) -> MapErr<Self, F> {
MapErr(self, f)
}
}
@ -113,9 +112,10 @@ where
A: InputValueValidator,
B: InputValueValidator,
{
fn is_valid(&self, value: &Value) -> Result<(), String> {
self.0.is_valid(value)?;
self.1.is_valid(value)
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
// By default, use is_valid method to keep compatible with previous version
self.0.is_valid_with_extensions(value)?;
self.1.is_valid_with_extensions(value)
}
}
@ -127,9 +127,10 @@ where
A: InputValueValidator,
B: InputValueValidator,
{
fn is_valid(&self, value: &Value) -> Result<(), String> {
if self.0.is_valid(value).is_err() {
self.1.is_valid(value)
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
// By default, use is_valid method to keep compatible with previous version
if self.0.is_valid_with_extensions(value).is_err() {
self.1.is_valid_with_extensions(value)
} else {
Ok(())
}
@ -142,9 +143,9 @@ pub struct MapErr<I, F>(I, F);
impl<I, F> InputValueValidator for MapErr<I, F>
where
I: InputValueValidator,
F: Fn(String) -> String + Send + Sync,
F: Fn(Error) -> Error + Send + Sync,
{
fn is_valid(&self, value: &Value) -> Result<(), String> {
self.0.is_valid(value).map_err(&self.1)
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
self.0.is_valid_with_extensions(value).map_err(&self.1)
}
}