add tests for WithRejection and Cached; update README.md
This commit is contained in:
@@ -7,11 +7,11 @@
|
|||||||
[](https://github.com/gengteng/axum-valid/actions/workflows/ci.yml)
|
[](https://github.com/gengteng/axum-valid/actions/workflows/ci.yml)
|
||||||
[](https://coveralls.io/github/gengteng/axum-valid?branch=main)
|
[](https://coveralls.io/github/gengteng/axum-valid?branch=main)
|
||||||
|
|
||||||
This crate provides a `Valid` type that can be used in combination with `Json`, `Path`, `Query`, and `Form` extractors to validate the entities that implement the `Validate` trait from the `validator` crate.
|
This crate provides a `Valid` type for use with `Json`, `Path`, `Query`, and `Form` extractors to validate entities implementing the `Validate` trait from the `validator` crate.
|
||||||
|
|
||||||
It also provides a `ValidEx` type that works similarly to `Valid`, but can perform validation requiring additional arguments by using types that implement the `ValidateArgs` trait.
|
A `ValidEx` type is also available. Similar to `Valid`, `ValidEx` can execute validations requiring extra arguments with types that implement the `ValidateArgs` trait from the `validator` crate.
|
||||||
|
|
||||||
Additional extractors like `TypedHeader`, `MsgPack`, `Yaml` etc. are supported through optional features. The full list of supported extractors is in the Features section below.
|
Additional extractors such as `TypedHeader`, `MsgPack`, `Yaml`, and others are supported through optional features. The complete list of supported extractors can be found in the Features section below.
|
||||||
|
|
||||||
## Basic usage
|
## Basic usage
|
||||||
|
|
||||||
|
|||||||
72
src/test.rs
72
src/test.rs
@@ -1,5 +1,5 @@
|
|||||||
use crate::tests::{ValidTest, ValidTestParameter};
|
use crate::tests::{ValidTest, ValidTestParameter};
|
||||||
use crate::{Arguments, HasValidate, Valid, ValidEx, VALIDATION_ERROR_STATUS};
|
use crate::{Arguments, HasValidate, HasValidateArgs, Valid, ValidEx, VALIDATION_ERROR_STATUS};
|
||||||
use axum::extract::{FromRef, Path, Query};
|
use axum::extract::{FromRef, Path, Query};
|
||||||
use axum::routing::{get, post};
|
use axum::routing::{get, post};
|
||||||
use axum::{Form, Json, Router};
|
use axum::{Form, Json, Router};
|
||||||
@@ -114,6 +114,14 @@ impl HasValidate for Parameters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'v> HasValidateArgs<'v> for ParametersEx {
|
||||||
|
type ValidateArgs = ParametersEx;
|
||||||
|
|
||||||
|
fn get_validate_args(&self) -> &Self::ValidateArgs {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, FromRef)]
|
#[derive(Debug, Clone, FromRef)]
|
||||||
struct MyState {
|
struct MyState {
|
||||||
param_validation_ctx: ParametersExValidationArguments,
|
param_validation_ctx: ParametersExValidationArguments,
|
||||||
@@ -172,13 +180,22 @@ async fn test_main() -> anyhow::Result<()> {
|
|||||||
#[cfg(feature = "extra")]
|
#[cfg(feature = "extra")]
|
||||||
let router = router
|
let router = router
|
||||||
.route(extra::route::CACHED, post(extra::extract_cached))
|
.route(extra::route::CACHED, post(extra::extract_cached))
|
||||||
|
.route(extra::route::CACHED_EX, post(extra::extract_cached_ex))
|
||||||
.route(
|
.route(
|
||||||
extra::route::WITH_REJECTION,
|
extra::route::WITH_REJECTION,
|
||||||
post(extra::extract_with_rejection),
|
post(extra::extract_with_rejection),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
extra::route::WITH_REJECTION_EX,
|
||||||
|
post(extra::extract_with_rejection_ex),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
extra::route::WITH_REJECTION_VALID,
|
extra::route::WITH_REJECTION_VALID,
|
||||||
post(extra::extract_with_rejection_valid),
|
post(extra::extract_with_rejection_valid),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
extra::route::WITH_REJECTION_VALID_EX,
|
||||||
|
post(extra::extract_with_rejection_valid_ex),
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "extra_typed_path")]
|
#[cfg(feature = "extra_typed_path")]
|
||||||
@@ -875,9 +892,12 @@ mod typed_multipart {
|
|||||||
|
|
||||||
#[cfg(feature = "extra")]
|
#[cfg(feature = "extra")]
|
||||||
mod extra {
|
mod extra {
|
||||||
use crate::test::{validate_again, Parameters};
|
use crate::test::{
|
||||||
|
validate_again, validate_again_ex, Parameters, ParametersEx,
|
||||||
|
ParametersExValidationArguments,
|
||||||
|
};
|
||||||
use crate::tests::{Rejection, ValidTest, ValidTestParameter};
|
use crate::tests::{Rejection, ValidTest, ValidTestParameter};
|
||||||
use crate::{Valid, ValidRejection};
|
use crate::{Arguments, Valid, ValidEx, ValidRejection};
|
||||||
use axum::extract::FromRequestParts;
|
use axum::extract::FromRequestParts;
|
||||||
use axum::http::request::Parts;
|
use axum::http::request::Parts;
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
@@ -887,8 +907,11 @@ mod extra {
|
|||||||
|
|
||||||
pub mod route {
|
pub mod route {
|
||||||
pub const CACHED: &str = "/cached";
|
pub const CACHED: &str = "/cached";
|
||||||
|
pub const CACHED_EX: &str = "/cached_ex";
|
||||||
pub const WITH_REJECTION: &str = "/with_rejection";
|
pub const WITH_REJECTION: &str = "/with_rejection";
|
||||||
|
pub const WITH_REJECTION_EX: &str = "/with_rejection_ex";
|
||||||
pub const WITH_REJECTION_VALID: &str = "/with_rejection_valid";
|
pub const WITH_REJECTION_VALID: &str = "/with_rejection_valid";
|
||||||
|
pub const WITH_REJECTION_VALID_EX: &str = "/with_rejection_valid_ex";
|
||||||
}
|
}
|
||||||
pub const PARAMETERS_HEADER: &str = "parameters-header";
|
pub const PARAMETERS_HEADER: &str = "parameters-header";
|
||||||
pub const CACHED_REJECTION_STATUS: StatusCode = StatusCode::FORBIDDEN;
|
pub const CACHED_REJECTION_STATUS: StatusCode = StatusCode::FORBIDDEN;
|
||||||
@@ -931,6 +954,22 @@ mod extra {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[axum::async_trait]
|
||||||
|
impl<S> FromRequestParts<S> for ParametersEx
|
||||||
|
where
|
||||||
|
S: Send + Sync,
|
||||||
|
{
|
||||||
|
type Rejection = ParametersRejection;
|
||||||
|
|
||||||
|
async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
|
||||||
|
let Some(value) = parts.headers.get(PARAMETERS_HEADER) else {
|
||||||
|
return Err(ParametersRejection::Null);
|
||||||
|
};
|
||||||
|
|
||||||
|
serde_json::from_slice(value.as_bytes()).map_err(ParametersRejection::InvalidJson)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ValidTest for Parameters {
|
impl ValidTest for Parameters {
|
||||||
const ERROR_STATUS_CODE: StatusCode = CACHED_REJECTION_STATUS;
|
const ERROR_STATUS_CODE: StatusCode = CACHED_REJECTION_STATUS;
|
||||||
|
|
||||||
@@ -987,6 +1026,15 @@ mod extra {
|
|||||||
validate_again(parameters)
|
validate_again(parameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn extract_cached_ex(
|
||||||
|
ValidEx(Cached(parameters), args): ValidEx<
|
||||||
|
Cached<ParametersEx>,
|
||||||
|
ParametersExValidationArguments,
|
||||||
|
>,
|
||||||
|
) -> StatusCode {
|
||||||
|
validate_again_ex(parameters, args.get())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn extract_with_rejection(
|
pub async fn extract_with_rejection(
|
||||||
Valid(WithRejection(parameters, _)): Valid<
|
Valid(WithRejection(parameters, _)): Valid<
|
||||||
WithRejection<Parameters, ValidWithRejectionRejection>,
|
WithRejection<Parameters, ValidWithRejectionRejection>,
|
||||||
@@ -995,6 +1043,15 @@ mod extra {
|
|||||||
validate_again(parameters)
|
validate_again(parameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn extract_with_rejection_ex(
|
||||||
|
ValidEx(WithRejection(parameters, _), args): ValidEx<
|
||||||
|
WithRejection<ParametersEx, ValidWithRejectionRejection>,
|
||||||
|
ParametersExValidationArguments,
|
||||||
|
>,
|
||||||
|
) -> StatusCode {
|
||||||
|
validate_again_ex(parameters, args.get())
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WithRejectionValidRejection<E> {
|
pub struct WithRejectionValidRejection<E> {
|
||||||
inner: ValidRejection<E>,
|
inner: ValidRejection<E>,
|
||||||
}
|
}
|
||||||
@@ -1021,6 +1078,15 @@ mod extra {
|
|||||||
) -> StatusCode {
|
) -> StatusCode {
|
||||||
validate_again(parameters)
|
validate_again(parameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn extract_with_rejection_valid_ex(
|
||||||
|
WithRejection(ValidEx(parameters, args), _): WithRejection<
|
||||||
|
ValidEx<ParametersEx, ParametersExValidationArguments>,
|
||||||
|
WithRejectionValidRejection<ParametersRejection>,
|
||||||
|
>,
|
||||||
|
) -> StatusCode {
|
||||||
|
validate_again_ex(parameters, args.get())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "extra_typed_path")]
|
#[cfg(feature = "extra_typed_path")]
|
||||||
|
|||||||
Reference in New Issue
Block a user