diff --git a/Cargo.toml b/Cargo.toml index fd45fb0..8d2b92a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "axum-valid" -version = "0.3.0" +version = "0.4.0" description = "Validation tools for axum using the validator library." authors = ["GengTeng "] license = "MIT" @@ -23,6 +23,11 @@ edition = "2021" axum = { version = "0.6.18", default-features = false } validator = "0.16.0" +[dependencies.serde_json] +package = "serde_json" +version = "1.0.103" +optional = true + [dev-dependencies] anyhow = "1.0.71" axum = { version = "0.6.18" } @@ -38,3 +43,4 @@ default = ["json", "form", "query"] json = ["axum/json"] form = ["axum/form"] query = ["axum/query"] +into_json = ["serde_json"] diff --git a/README.md b/README.md index 9a4a9ef..b714164 100644 --- a/README.md +++ b/README.md @@ -44,4 +44,8 @@ pub async fn get_page_by_json( } ``` -For more usage examples, please refer to the `basic.rs` and `custom.rs` files in the `tests` directory. \ No newline at end of file +For more usage examples, please refer to the `basic.rs` and `custom.rs` files in the `tests` directory. + +## Features + +`into_json`: When this feature is enabled, validation errors will be serialized into JSON format and returned as the HTTP body. \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index fd2cfc0..1fab405 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,8 +39,17 @@ impl IntoResponse for ValidRejection { fn into_response(self) -> Response { match self { ValidRejection::Valid(validate_error) => { - (StatusCode::BAD_REQUEST, validate_error.to_string()).into_response() - } + #[cfg(feature = "into_json")] + match serde_json::to_string(&validate_error) { + Ok(json) => (StatusCode::BAD_REQUEST, json), + Err(error) => ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to serialize validation error into JSON ({validate_error}): {error}"), + ), + } + #[cfg(not(feature = "into_json"))] + (StatusCode::BAD_REQUEST, validate_error.to_string()) + }.into_response(), ValidRejection::Inner(json_error) => json_error.into_response(), } } diff --git a/tarpaulin.toml b/tarpaulin.toml new file mode 100644 index 0000000..f7638a1 --- /dev/null +++ b/tarpaulin.toml @@ -0,0 +1,4 @@ +[feature_default] + +[feature_into_json] +features = "into_json" \ No newline at end of file diff --git a/tests/basic.rs b/tests/basic.rs index 82d071c..c5f1855 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -77,6 +77,11 @@ async fn main() -> anyhow::Result<()> { .send() .await?; assert_eq!(invalid_path_response.status(), StatusCode::BAD_REQUEST); + #[cfg(feature = "into_json")] + assert!(invalid_path_response + .json::() + .await + .is_ok()); println!("Valid> works."); // Valid> @@ -101,6 +106,11 @@ async fn main() -> anyhow::Result<()> { .send() .await?; assert_eq!(invalid_query_response.status(), StatusCode::BAD_REQUEST); + #[cfg(feature = "into_json")] + assert!(invalid_query_response + .json::() + .await + .is_ok()); println!("Valid> works."); // Valid> @@ -128,6 +138,11 @@ async fn main() -> anyhow::Result<()> { .send() .await?; assert_eq!(invalid_form_response.status(), StatusCode::BAD_REQUEST); + #[cfg(feature = "into_json")] + assert!(invalid_form_response + .json::() + .await + .is_ok()); println!("Valid> works."); // Valid> @@ -155,6 +170,11 @@ async fn main() -> anyhow::Result<()> { .send() .await?; assert_eq!(invalid_json_response.status(), StatusCode::BAD_REQUEST); + #[cfg(feature = "into_json")] + assert!(invalid_json_response + .json::() + .await + .is_ok()); println!("Valid> works."); drop(server_guard); diff --git a/tests/custom.rs b/tests/custom.rs index 0ee63a1..3f46daf 100644 --- a/tests/custom.rs +++ b/tests/custom.rs @@ -123,6 +123,11 @@ async fn main() -> anyhow::Result<()> { .send() .await?; assert_eq!(invalid_my_data_response.status(), StatusCode::BAD_REQUEST); + #[cfg(feature = "into_json")] + assert!(invalid_my_data_response + .json::() + .await + .is_ok()); println!("Valid works."); drop(server_guard);