Skip to content

Commit

Permalink
Add struct NoContent as a self-described shortcut
Browse files Browse the repository at this point in the history
We cannot change the behavior of `<() as IntoResponse>::into_response`,
so add a newtype struct to explicitly use 204 No Content status.

Refs: #2363, #2393
  • Loading branch information
oxalica committed Oct 11, 2024
1 parent c6e6b4e commit d5f9bd0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
2 changes: 2 additions & 0 deletions axum/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]`
Expand All @@ -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

Expand Down
35 changes: 34 additions & 1 deletion axum/src/response/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![doc = include_str!("../docs/response.md")]

use http::{header, HeaderValue};
use http::{header, HeaderValue, StatusCode};

mod redirect;

Expand Down Expand Up @@ -59,6 +59,31 @@ impl<T> From<T> for Html<T> {
}
}

/// 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<String>) -> Result<NoContent, String> {
/// // ...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;
Expand Down Expand Up @@ -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,
)
}
}

0 comments on commit d5f9bd0

Please sign in to comment.