From 0712a46cd9f2bece74160e83085411aa0c174be1 Mon Sep 17 00:00:00 2001 From: oxalica Date: Fri, 11 Oct 2024 11:54:11 -0400 Subject: [PATCH] Add `struct NoContent` as a self-described shortcut (#2978) --- axum/CHANGELOG.md | 2 ++ axum/src/response/mod.rs | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md index b3529d19..58b2b555 100644 --- a/axum/CHANGELOG.md +++ b/axum/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased +- **added:** Add `NoContent` as a self-described shortcut for `StatusCode::NO_CONTENT` ([#2978]) - **added:** Add support for WebSockets over HTTP/2 ([#2894]). They can be enabled by changing `get(ws_endpoint)` handlers to `any(ws_endpoint)` - **added:** Add `MethodFilter::CONNECT`, `routing::connect[_service]` @@ -20,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#2984]: https://github.com/tokio-rs/axum/pull/2984 [#2961]: https://github.com/tokio-rs/axum/pull/2961 [#2974]: https://github.com/tokio-rs/axum/pull/2974 +[#2978]: https://github.com/tokio-rs/axum/pull/2978 # 0.8.0 diff --git a/axum/src/response/mod.rs b/axum/src/response/mod.rs index 632df5cb..dd616dff 100644 --- a/axum/src/response/mod.rs +++ b/axum/src/response/mod.rs @@ -1,6 +1,6 @@ #![doc = include_str!("../docs/response.md")] -use http::{header, HeaderValue}; +use http::{header, HeaderValue, StatusCode}; mod redirect; @@ -59,6 +59,31 @@ impl From for Html { } } +/// An empty response with 204 No Content status. +/// +/// Due to historical and implementation reasons, the `IntoResponse` implementation of `()` +/// (unit type) returns an empty response with 200 [`StatusCode::OK`] status. +/// If you specifically want a 204 [`StatusCode::NO_CONTENT`] status, you can use either `StatusCode` type +/// directly, or this shortcut struct for self-documentation. +/// +/// ``` +/// use axum::{extract::Path, response::NoContent}; +/// +/// async fn delete_user(Path(user): Path) -> Result { +/// // ...access database... +/// # drop(user); +/// Ok(NoContent) +/// } +/// ``` +#[derive(Debug, Clone, Copy)] +pub struct NoContent; + +impl IntoResponse for NoContent { + fn into_response(self) -> Response { + StatusCode::NO_CONTENT.into_response() + } +} + #[cfg(test)] mod tests { use crate::extract::Extension; @@ -223,4 +248,12 @@ mod tests { .route("/", get(header_array_extension_body)) .route("/", get(header_array_extension_mixed_body)); } + + #[test] + fn no_content() { + assert_eq!( + super::NoContent.into_response().status(), + StatusCode::NO_CONTENT, + ) + } }