add feature 422 and update version to 0.4.0
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
/Cargo.lock
|
/Cargo.lock
|
||||||
/.idea
|
/.idea
|
||||||
|
/lcov.info
|
||||||
|
|||||||
@@ -44,3 +44,4 @@ json = ["axum/json"]
|
|||||||
form = ["axum/form"]
|
form = ["axum/form"]
|
||||||
query = ["axum/query"]
|
query = ["axum/query"]
|
||||||
into_json = ["serde_json"]
|
into_json = ["serde_json"]
|
||||||
|
422 = []
|
||||||
|
|||||||
@@ -44,8 +44,11 @@ pub async fn get_page_by_json(
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
When validation errors occur, the extractor will automatically return 400 with validation errors as the HTTP message body.
|
||||||
|
|
||||||
For more usage examples, please refer to the `basic.rs` and `custom.rs` files in the `tests` directory.
|
For more usage examples, please refer to the `basic.rs` and `custom.rs` files in the `tests` directory.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
`422`: Use `422 Unprocessable Entity` instead of `400 Bad Request` as the status code when validation fails.
|
||||||
`into_json`: When this feature is enabled, validation errors will be serialized into JSON format and returned as the HTTP body.
|
`into_json`: When this feature is enabled, validation errors will be serialized into JSON format and returned as the HTTP body.
|
||||||
11
src/lib.rs
11
src/lib.rs
@@ -16,6 +16,13 @@ use axum::http::{Request, StatusCode};
|
|||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use validator::{Validate, ValidationErrors};
|
use validator::{Validate, ValidationErrors};
|
||||||
|
|
||||||
|
/// Http status code returned when there are validation errors.
|
||||||
|
#[cfg(feature = "422")]
|
||||||
|
pub const VALIDATION_ERROR_STATUS: StatusCode = StatusCode::UNPROCESSABLE_ENTITY;
|
||||||
|
/// Http status code returned when there are validation errors.
|
||||||
|
#[cfg(not(feature = "422"))]
|
||||||
|
pub const VALIDATION_ERROR_STATUS: StatusCode = StatusCode::BAD_REQUEST;
|
||||||
|
|
||||||
/// Valid entity extractor
|
/// Valid entity extractor
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct Valid<T>(pub T);
|
pub struct Valid<T>(pub T);
|
||||||
@@ -41,14 +48,14 @@ impl<E: IntoResponse> IntoResponse for ValidRejection<E> {
|
|||||||
ValidRejection::Valid(validate_error) => {
|
ValidRejection::Valid(validate_error) => {
|
||||||
#[cfg(feature = "into_json")]
|
#[cfg(feature = "into_json")]
|
||||||
match serde_json::to_string(&validate_error) {
|
match serde_json::to_string(&validate_error) {
|
||||||
Ok(json) => (StatusCode::BAD_REQUEST, json),
|
Ok(json) => (VALIDATION_ERROR_STATUS, json),
|
||||||
Err(error) => (
|
Err(error) => (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("Failed to serialize validation error into JSON ({validate_error}): {error}"),
|
format!("Failed to serialize validation error into JSON ({validate_error}): {error}"),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "into_json"))]
|
#[cfg(not(feature = "into_json"))]
|
||||||
(StatusCode::BAD_REQUEST, validate_error.to_string())
|
(VALIDATION_ERROR_STATUS, validate_error.to_string())
|
||||||
}.into_response(),
|
}.into_response(),
|
||||||
ValidRejection::Inner(json_error) => json_error.into_response(),
|
ValidRejection::Inner(json_error) => json_error.into_response(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
[feature_default]
|
[feature_default]
|
||||||
|
|
||||||
[feature_into_json]
|
[feature_into_json]
|
||||||
features = "into_json"
|
features = "into_json"
|
||||||
|
|
||||||
|
[feature_422]
|
||||||
|
features = "422"
|
||||||
|
|
||||||
|
[feature_422_into_json]
|
||||||
|
features = "422 into_json"
|
||||||
@@ -9,7 +9,7 @@ use axum::extract::{Path, Query};
|
|||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::routing::{get, post};
|
use axum::routing::{get, post};
|
||||||
use axum::{Form, Json, Router};
|
use axum::{Form, Json, Router};
|
||||||
use axum_valid::Valid;
|
use axum_valid::{Valid, VALIDATION_ERROR_STATUS};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
@@ -76,7 +76,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
))
|
))
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(invalid_path_response.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(invalid_path_response.status(), VALIDATION_ERROR_STATUS);
|
||||||
#[cfg(feature = "into_json")]
|
#[cfg(feature = "into_json")]
|
||||||
assert!(invalid_path_response
|
assert!(invalid_path_response
|
||||||
.json::<serde_json::Value>()
|
.json::<serde_json::Value>()
|
||||||
@@ -105,7 +105,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.query(&invalid_parameters)
|
.query(&invalid_parameters)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(invalid_query_response.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(invalid_query_response.status(), VALIDATION_ERROR_STATUS);
|
||||||
#[cfg(feature = "into_json")]
|
#[cfg(feature = "into_json")]
|
||||||
assert!(invalid_query_response
|
assert!(invalid_query_response
|
||||||
.json::<serde_json::Value>()
|
.json::<serde_json::Value>()
|
||||||
@@ -137,7 +137,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.form(&invalid_parameters)
|
.form(&invalid_parameters)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(invalid_form_response.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(invalid_form_response.status(), VALIDATION_ERROR_STATUS);
|
||||||
#[cfg(feature = "into_json")]
|
#[cfg(feature = "into_json")]
|
||||||
assert!(invalid_form_response
|
assert!(invalid_form_response
|
||||||
.json::<serde_json::Value>()
|
.json::<serde_json::Value>()
|
||||||
@@ -169,7 +169,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.json(&invalid_parameters)
|
.json(&invalid_parameters)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(invalid_json_response.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(invalid_json_response.status(), VALIDATION_ERROR_STATUS);
|
||||||
#[cfg(feature = "into_json")]
|
#[cfg(feature = "into_json")]
|
||||||
assert!(invalid_json_response
|
assert!(invalid_json_response
|
||||||
.json::<serde_json::Value>()
|
.json::<serde_json::Value>()
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use axum::http::request::Parts;
|
|||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use axum::routing::get;
|
use axum::routing::get;
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use axum_valid::{HasValidate, Valid, ValidRejection};
|
use axum_valid::{HasValidate, Valid, ValidRejection, VALIDATION_ERROR_STATUS};
|
||||||
use hyper::StatusCode;
|
use hyper::StatusCode;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
@@ -122,7 +122,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.header(MY_DATA_HEADER, serde_json::to_string(&invalid_my_data)?)
|
.header(MY_DATA_HEADER, serde_json::to_string(&invalid_my_data)?)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(invalid_my_data_response.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(invalid_my_data_response.status(), VALIDATION_ERROR_STATUS);
|
||||||
#[cfg(feature = "into_json")]
|
#[cfg(feature = "into_json")]
|
||||||
assert!(invalid_my_data_response
|
assert!(invalid_my_data_response
|
||||||
.json::<serde_json::Value>()
|
.json::<serde_json::Value>()
|
||||||
|
|||||||
Reference in New Issue
Block a user