Update AND, OR, and MapErr logic. Update logic for object input
This commit is contained in:
parent
abb59b9e3f
commit
0417f4181a
@ -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(
|
is_valid_input_value(
|
||||||
ctx.registry,
|
ctx.registry,
|
||||||
&arg.ty,
|
&arg.ty,
|
||||||
@ -79,9 +79,10 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
ctx.report_error(
|
ctx.report_error_with_extensions(
|
||||||
vec![name.pos],
|
vec![name.pos],
|
||||||
format!("Invalid value for argument {}", reason),
|
format!("Invalid value for argument {}", e.message),
|
||||||
|
e.extensions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
"Argument \"{}\" has type \"{}\" and is not nullable, so it can't have a default value",
|
||||||
variable_definition.node.name, variable_definition.node.var_type,
|
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,
|
ctx.registry,
|
||||||
&variable_definition.node.var_type.to_string(),
|
&variable_definition.node.var_type.to_string(),
|
||||||
&value.node,
|
&value.node,
|
||||||
@ -27,9 +27,10 @@ impl<'a> Visitor<'a> for DefaultValuesOfCorrectType {
|
|||||||
segment: QueryPathSegment::Name(&variable_definition.node.name.node),
|
segment: QueryPathSegment::Name(&variable_definition.node.name.node),
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
ctx.report_error(
|
ctx.report_error_with_extensions(
|
||||||
vec![variable_definition.pos],
|
vec![variable_definition.pos],
|
||||||
format!("Invalid default value for argument {}", reason),
|
format!("Invalid default value for argument {}", e.message),
|
||||||
|
e.extensions,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use crate::context::QueryPathNode;
|
|
||||||
use crate::{registry, QueryPathSegment};
|
|
||||||
use async_graphql_value::{ConstValue, Value};
|
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)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Scope<'a> {
|
pub enum Scope<'a> {
|
||||||
Operation(Option<&'a str>),
|
Operation(Option<&'a str>),
|
||||||
@ -40,13 +42,12 @@ pub fn is_valid_input_value(
|
|||||||
type_name: &str,
|
type_name: &str,
|
||||||
value: &ConstValue,
|
value: &ConstValue,
|
||||||
path_node: QueryPathNode,
|
path_node: QueryPathNode,
|
||||||
) -> Option<String> {
|
) -> Option<Error> {
|
||||||
match registry::MetaTypeName::create(type_name) {
|
match registry::MetaTypeName::create(type_name) {
|
||||||
registry::MetaTypeName::NonNull(type_name) => match value {
|
registry::MetaTypeName::NonNull(type_name) => match value {
|
||||||
ConstValue::Null => Some(valid_error(
|
ConstValue::Null => {
|
||||||
&path_node,
|
Some(valid_error(&path_node, format!("expected type \"{}\"", type_name)).into())
|
||||||
format!("expected type \"{}\"", type_name),
|
}
|
||||||
)),
|
|
||||||
_ => is_valid_input_value(registry, type_name, value, path_node),
|
_ => is_valid_input_value(registry, type_name, value, path_node),
|
||||||
},
|
},
|
||||||
registry::MetaTypeName::List(type_name) => match value {
|
registry::MetaTypeName::List(type_name) => match value {
|
||||||
@ -74,10 +75,10 @@ pub fn is_valid_input_value(
|
|||||||
if is_valid(&value) {
|
if is_valid(&value) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(valid_error(
|
Some(
|
||||||
&path_node,
|
valid_error(&path_node, format!("expected type \"{}\"", type_name))
|
||||||
format!("expected type \"{}\"", type_name),
|
.into(),
|
||||||
))
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
registry::MetaType::Enum {
|
registry::MetaType::Enum {
|
||||||
@ -87,34 +88,39 @@ pub fn is_valid_input_value(
|
|||||||
} => match value {
|
} => match value {
|
||||||
ConstValue::Enum(name) => {
|
ConstValue::Enum(name) => {
|
||||||
if !enum_values.contains_key(name.as_str()) {
|
if !enum_values.contains_key(name.as_str()) {
|
||||||
Some(valid_error(
|
Some(
|
||||||
|
valid_error(
|
||||||
&path_node,
|
&path_node,
|
||||||
format!(
|
format!(
|
||||||
"enumeration type \"{}\" does not contain the value \"{}\"",
|
"enumeration type \"{}\" does not contain the value \"{}\"",
|
||||||
enum_name, name
|
enum_name, name
|
||||||
),
|
),
|
||||||
))
|
)
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConstValue::String(name) => {
|
ConstValue::String(name) => {
|
||||||
if !enum_values.contains_key(name.as_str()) {
|
if !enum_values.contains_key(name.as_str()) {
|
||||||
Some(valid_error(
|
Some(
|
||||||
|
valid_error(
|
||||||
&path_node,
|
&path_node,
|
||||||
format!(
|
format!(
|
||||||
"enumeration type \"{}\" does not contain the value \"{}\"",
|
"enumeration type \"{}\" does not contain the value \"{}\"",
|
||||||
enum_name, name
|
enum_name, name
|
||||||
),
|
),
|
||||||
))
|
)
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Some(valid_error(
|
_ => Some(
|
||||||
&path_node,
|
valid_error(&path_node, format!("expected type \"{}\"", type_name)).into(),
|
||||||
format!("expected type \"{}\"", type_name),
|
),
|
||||||
)),
|
|
||||||
},
|
},
|
||||||
registry::MetaType::InputObject {
|
registry::MetaType::InputObject {
|
||||||
input_fields,
|
input_fields,
|
||||||
@ -129,14 +135,15 @@ pub fn is_valid_input_value(
|
|||||||
input_names.remove(field.name);
|
input_names.remove(field.name);
|
||||||
if let Some(value) = values.get(field.name) {
|
if let Some(value) = values.get(field.name) {
|
||||||
if let Some(validator) = &field.validator {
|
if let Some(validator) = &field.validator {
|
||||||
if let Err(reason) = validator.is_valid(value) {
|
if let Err(mut e) = validator.is_valid_with_extensions(value) {
|
||||||
return Some(valid_error(
|
e.message = valid_error(
|
||||||
&QueryPathNode {
|
&QueryPathNode {
|
||||||
parent: Some(&path_node),
|
parent: Some(&path_node),
|
||||||
segment: QueryPathSegment::Name(field.name),
|
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()
|
} else if registry::MetaTypeName::create(&field.ty).is_non_null()
|
||||||
&& field.default_value.is_none()
|
&& field.default_value.is_none()
|
||||||
{
|
{
|
||||||
return Some(valid_error(
|
return Some(
|
||||||
|
valid_error(
|
||||||
&path_node,
|
&path_node,
|
||||||
format!(
|
format!(
|
||||||
"field \"{}\" of type \"{}\" is required but not provided",
|
"field \"{}\" of type \"{}\" is required but not provided",
|
||||||
field.name, object_name,
|
field.name, object_name,
|
||||||
),
|
),
|
||||||
));
|
)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(name) = input_names.iter().next() {
|
if let Some(name) = input_names.iter().next() {
|
||||||
return Some(valid_error(
|
return Some(
|
||||||
|
valid_error(
|
||||||
&path_node,
|
&path_node,
|
||||||
format!("unknown field \"{}\" of type \"{}\"", name, object_name),
|
format!(
|
||||||
));
|
"unknown field \"{}\" of type \"{}\"",
|
||||||
|
name, object_name
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -80,8 +80,7 @@ where
|
|||||||
/// ```
|
/// ```
|
||||||
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
|
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
|
||||||
// By default, use is_valid method to keep compatible with previous version
|
// By default, use is_valid method to keep compatible with previous version
|
||||||
self.is_valid(value)?;
|
self.is_valid(value).map_err(|reason| Error::new(reason))
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +97,7 @@ pub trait InputValueValidatorExt: InputValueValidator + Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Changes the error message
|
/// 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)
|
MapErr(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,9 +112,10 @@ where
|
|||||||
A: InputValueValidator,
|
A: InputValueValidator,
|
||||||
B: InputValueValidator,
|
B: InputValueValidator,
|
||||||
{
|
{
|
||||||
fn is_valid(&self, value: &Value) -> Result<(), String> {
|
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
|
||||||
self.0.is_valid(value)?;
|
// By default, use is_valid method to keep compatible with previous version
|
||||||
self.1.is_valid(value)
|
self.0.is_valid_with_extensions(value)?;
|
||||||
|
self.1.is_valid_with_extensions(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,9 +127,10 @@ where
|
|||||||
A: InputValueValidator,
|
A: InputValueValidator,
|
||||||
B: InputValueValidator,
|
B: InputValueValidator,
|
||||||
{
|
{
|
||||||
fn is_valid(&self, value: &Value) -> Result<(), String> {
|
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
|
||||||
if self.0.is_valid(value).is_err() {
|
// By default, use is_valid method to keep compatible with previous version
|
||||||
self.1.is_valid(value)
|
if self.0.is_valid_with_extensions(value).is_err() {
|
||||||
|
self.1.is_valid_with_extensions(value)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -142,9 +143,9 @@ pub struct MapErr<I, F>(I, F);
|
|||||||
impl<I, F> InputValueValidator for MapErr<I, F>
|
impl<I, F> InputValueValidator for MapErr<I, F>
|
||||||
where
|
where
|
||||||
I: InputValueValidator,
|
I: InputValueValidator,
|
||||||
F: Fn(String) -> String + Send + Sync,
|
F: Fn(Error) -> Error + Send + Sync,
|
||||||
{
|
{
|
||||||
fn is_valid(&self, value: &Value) -> Result<(), String> {
|
fn is_valid_with_extensions(&self, value: &Value) -> Result<(), Error> {
|
||||||
self.0.is_valid(value).map_err(&self.1)
|
self.0.is_valid_with_extensions(value).map_err(&self.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user