Remove the `ctx` parameter of `CustomValidator::check`. #710

This commit is contained in:
Sunli 2021-11-17 08:46:13 +08:00
parent fb7465dcb7
commit af25734697
6 changed files with 58 additions and 9 deletions

View File

@ -82,7 +82,7 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult<TokenStream>
.create_validators(
&crate_name,
quote!(&#ident),
quote!(ty),
quote!(#ty),
Some(quote!(.map_err(#crate_name::InputValueError::propagate))),
)?;

View File

@ -138,7 +138,7 @@ impl Validators {
let expr: Expr =
syn::parse_str(s).map_err(|err| Error::new(s.span(), err.to_string()))?;
codes.push(quote! {
#crate_name::CustomValidator::check(&(#expr), &ctx, #value).await
#crate_name::CustomValidator::check(&(#expr), #value)
.map_err(|err_msg| #crate_name::InputValueError::<#ty>::custom(err_msg))
});
}

View File

@ -57,7 +57,7 @@ impl MyValidator {
#[async_trait::async_trait]
impl CustomValidator<i32> for MyValidator {
async fn check(&self, _ctx: &Context<'_>, value: &i32) -> Result<(), String> {
async fn check(&self, value: &i32) -> Result<(), String> {
if *value == self.expect {
Ok(())
} else {

View File

@ -57,7 +57,7 @@ impl MyValidator {
#[async_trait::async_trait]
impl CustomValidator<i32> for MyValidator {
async fn check(&self, _ctx: &Context<'_>, value: &i32) -> Result<(), String> {
async fn check(&self, value: &i32) -> Result<(), String> {
if *value == self.expect {
Ok(())
} else {

View File

@ -20,11 +20,10 @@ pub use min_length::min_length;
pub use minimum::minimum;
pub use multiple_of::multiple_of;
use crate::{Context, InputType};
use crate::InputType;
/// Represents a custom input value validator.
#[async_trait::async_trait]
pub trait CustomValidator<T: InputType> {
/// Check the value is valid.
async fn check(&self, ctx: &Context<'_>, value: &T) -> Result<(), String>;
fn check(&self, value: &T) -> Result<(), String>;
}

View File

@ -266,9 +266,8 @@ pub async fn test_custom_validator() {
}
}
#[async_trait::async_trait]
impl CustomValidator<i32> for MyValidator {
async fn check(&self, _ctx: &Context<'_>, value: &i32) -> Result<(), String> {
fn check(&self, value: &i32) -> Result<(), String> {
if *value == self.expect {
Ok(())
} else {
@ -277,6 +276,12 @@ pub async fn test_custom_validator() {
}
}
#[derive(InputObject)]
struct MyInput {
#[graphql(validator(custom = "MyValidator::new(100)"))]
n: i32,
}
struct Query;
#[Object]
@ -287,6 +292,22 @@ pub async fn test_custom_validator() {
) -> i32 {
n
}
async fn input(&self, input: MyInput) -> i32 {
input.n
}
}
struct Subscription;
#[Subscription]
impl Subscription {
async fn value(
&self,
#[graphql(validator(custom = "MyValidator::new(100)"))] n: i32,
) -> impl Stream<Item = i32> {
futures_util::stream::iter(vec![n])
}
}
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
@ -317,6 +338,35 @@ pub async fn test_custom_validator() {
extensions: None
}]
);
assert_eq!(
schema
.execute("{ input(input: {n: 100} ) }")
.await
.into_result()
.unwrap()
.data,
value!({ "input": 100 })
);
assert_eq!(
schema
.execute("{ input(input: {n: 11} ) }")
.await
.into_result()
.unwrap_err(),
vec![ServerError {
message:
r#"Failed to parse "Int": expect 100, actual 11 (occurred while parsing "MyInput")"#
.to_string(),
source: None,
locations: vec![Pos {
line: 1,
column: 16
}],
path: vec![PathSegment::Field("input".to_string())],
extensions: None
}]
);
}
#[tokio::test]