Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ uninlined_format_args = "warn"
unnested_or_patterns = "warn"
unused_self = "warn"
verbose_file_reads = "warn"
must_use_candidate = "warn"

# configuration for https://github.com/crate-ci/typos
[workspace.metadata.typos.default.extend-identifiers]
Expand Down
2 changes: 2 additions & 0 deletions axum-core/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl Body {
}

/// Create an empty body.
#[must_use]
pub fn empty() -> Self {
Self::new(http_body_util::Empty::new())
}
Expand All @@ -72,6 +73,7 @@ impl Body {
/// you need a [`Stream`] of all frame types.
///
/// [`http_body_util::BodyStream`]: https://docs.rs/http-body-util/latest/http_body_util/struct.BodyStream.html
#[must_use]
pub fn into_data_stream(self) -> BodyDataStream {
BodyDataStream { inner: self }
}
Expand Down
1 change: 1 addition & 0 deletions axum-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ impl Error {
}

/// Convert an `Error` back into the underlying boxed trait object.
#[must_use]
pub fn into_inner(self) -> BoxError {
Comment on lines +19 to 20
Copy link
Collaborator

@mladedav mladedav Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For errors (and possibly other cases such as builders) we might want to add #[must_use] to the type rather than methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to avoid #[must_use] for the methods here, since BoxError is a type alias and not a "real" type. Adding #[must_use] to the Error struct doesn't do anything, either. Any ideas?

self.inner
}
Expand Down
4 changes: 4 additions & 0 deletions axum-core/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,13 @@ macro_rules! __define_rejection {
}

/// Get the response body text used for this rejection.
#[must_use]
pub fn body_text(&self) -> String {
self.to_string()
}

/// Get the status code used for this rejection.
#[must_use]
pub fn status(&self) -> http::StatusCode {
http::StatusCode::$status
}
Expand Down Expand Up @@ -179,6 +181,7 @@ macro_rules! __composite_rejection {

impl $name {
/// Get the response body text used for this rejection.
#[must_use]
pub fn body_text(&self) -> String {
match self {
$(
Expand All @@ -188,6 +191,7 @@ macro_rules! __composite_rejection {
}

/// Get the status code used for this rejection.
#[must_use]
pub fn status(&self) -> http::StatusCode {
match self {
$(
Expand Down
3 changes: 3 additions & 0 deletions axum-extra/src/extract/cookie/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ impl CookieJar {
/// run extractors. Normally you should create `CookieJar`s through [`FromRequestParts`].
///
/// [`FromRequestParts`]: axum::extract::FromRequestParts
#[must_use]
pub fn from_headers(headers: &HeaderMap) -> Self {
let mut jar = cookie::CookieJar::new();
for cookie in cookies_from_request(headers) {
Expand All @@ -135,6 +136,7 @@ impl CookieJar {
/// CookieJar`.
///
/// [`FromRequestParts`]: axum::extract::FromRequestParts
#[must_use]
pub fn new() -> Self {
Self::default()
}
Expand All @@ -153,6 +155,7 @@ impl CookieJar {
/// .map(|cookie| cookie.value().to_owned());
/// }
/// ```
#[must_use]
pub fn get(&self, name: &str) -> Option<&Cookie<'static>> {
self.jar.get(name)
}
Expand Down
4 changes: 4 additions & 0 deletions axum-extra/src/extract/cookie/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ impl PrivateCookieJar {
/// run extractors. Normally you should create `PrivateCookieJar`s through [`FromRequestParts`].
///
/// [`FromRequestParts`]: axum::extract::FromRequestParts
#[must_use]
pub fn from_headers(headers: &HeaderMap, key: Key) -> Self {
let mut jar = cookie::CookieJar::new();
let mut private_jar = jar.private_mut(&key);
Expand All @@ -175,6 +176,7 @@ impl PrivateCookieJar {
/// run extractors. Normally you should create `PrivateCookieJar`s through [`FromRequestParts`].
///
/// [`FromRequestParts`]: axum::extract::FromRequestParts
#[must_use]
pub fn new(key: Key) -> Self {
Self {
jar: Default::default(),
Expand All @@ -201,6 +203,7 @@ impl<K> PrivateCookieJar<K> {
/// .map(|cookie| cookie.value().to_owned());
/// }
/// ```
#[must_use]
pub fn get(&self, name: &str) -> Option<Cookie<'static>> {
self.private_jar().get(name)
}
Expand Down Expand Up @@ -246,6 +249,7 @@ impl<K> PrivateCookieJar<K> {

/// Authenticates and decrypts `cookie`, returning the plaintext version if decryption succeeds
/// or `None` otherwise.
#[must_use]
pub fn decrypt(&self, cookie: Cookie<'static>) -> Option<Cookie<'static>> {
self.private_jar().decrypt(cookie)
}
Expand Down
4 changes: 4 additions & 0 deletions axum-extra/src/extract/cookie/signed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ impl SignedCookieJar {
/// run extractors. Normally you should create `SignedCookieJar`s through [`FromRequestParts`].
///
/// [`FromRequestParts`]: axum::extract::FromRequestParts
#[must_use]
pub fn from_headers(headers: &HeaderMap, key: Key) -> Self {
let mut jar = cookie::CookieJar::new();
let mut signed_jar = jar.signed_mut(&key);
Expand All @@ -192,6 +193,7 @@ impl SignedCookieJar {
/// run extractors. Normally you should create `SignedCookieJar`s through [`FromRequestParts`].
///
/// [`FromRequestParts`]: axum::extract::FromRequestParts
#[must_use]
pub fn new(key: Key) -> Self {
Self {
jar: Default::default(),
Expand Down Expand Up @@ -219,6 +221,7 @@ impl<K> SignedCookieJar<K> {
/// .map(|cookie| cookie.value().to_owned());
/// }
/// ```
#[must_use]
pub fn get(&self, name: &str) -> Option<Cookie<'static>> {
self.signed_jar().get(name)
}
Expand Down Expand Up @@ -264,6 +267,7 @@ impl<K> SignedCookieJar<K> {

/// Verifies the authenticity and integrity of `cookie`, returning the plaintext version if
/// verification succeeds or `None` otherwise.
#[must_use]
pub fn verify(&self, cookie: Cookie<'static>) -> Option<Cookie<'static>> {
self.signed_jar().verify(cookie)
}
Expand Down
5 changes: 5 additions & 0 deletions axum-extra/src/extract/multipart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,23 +150,27 @@ impl Field {
/// The field name found in the
/// [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
/// header.
#[must_use]
pub fn name(&self) -> Option<&str> {
self.inner.name()
}

/// The file name found in the
/// [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
/// header.
#[must_use]
pub fn file_name(&self) -> Option<&str> {
self.inner.file_name()
}

/// Get the [content type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) of the field.
#[must_use]
pub fn content_type(&self) -> Option<&str> {
self.inner.content_type().map(|m| m.as_ref())
}

/// Get a map of headers as [`HeaderMap`].
#[must_use]
pub fn headers(&self) -> &HeaderMap {
self.inner.headers()
}
Expand Down Expand Up @@ -253,6 +257,7 @@ impl MultipartError {
}

/// Get the status code used for this rejection.
#[must_use]
pub fn status(&self) -> http::StatusCode {
status_code_from_multer_error(&self.source)
}
Expand Down
3 changes: 3 additions & 0 deletions axum-extra/src/response/multiple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl MultipartForm {
/// let parts: Vec<Part> = vec![Part::text("foo".to_string(), "abc"), Part::text("bar".to_string(), "def")];
/// let form = MultipartForm::with_parts(parts);
/// ```
#[must_use]
pub fn with_parts(parts: Vec<Part>) -> Self {
MultipartForm { parts }
}
Expand Down Expand Up @@ -103,6 +104,7 @@ impl Part {
/// let parts: Vec<Part> = vec![Part::text("foo".to_string(), "abc")];
/// let form = MultipartForm::from_iter(parts);
/// ```
#[must_use]
pub fn text(name: String, contents: &str) -> Self {
Self {
name,
Expand All @@ -127,6 +129,7 @@ impl Part {
/// let parts: Vec<Part> = vec![Part::file("foo", "foo.txt", vec![0x68, 0x68, 0x20, 0x6d, 0x6f, 0x6d])];
/// let form = MultipartForm::from_iter(parts);
/// ```
#[must_use]
pub fn file(field_name: &str, file_name: &str, contents: Vec<u8>) -> Self {
Self {
name: field_name.to_owned(),
Expand Down
1 change: 1 addition & 0 deletions axum-extra/src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub use self::typed::{SecondElementIs, TypedPath};
// Validates a path at compile time, used with the vpath macro.
#[rustversion::since(1.80)]
#[doc(hidden)]
#[must_use]
pub const fn __private_validate_static_path(path: &'static str) -> &'static str {
if path.is_empty() {
panic!("Paths must start with a `/`. Use \"/\" for root routes")
Expand Down
2 changes: 2 additions & 0 deletions axum-extra/src/typed_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,13 @@ pub struct TypedHeaderRejection {

impl TypedHeaderRejection {
/// Name of the header that caused the rejection
#[must_use]
pub fn name(&self) -> &http::header::HeaderName {
self.name
}

/// Reason why the header extraction has failed
#[must_use]
pub fn reason(&self) -> &TypedHeaderRejectionReason {
&self.reason
}
Expand Down
1 change: 1 addition & 0 deletions axum/src/extract/matched_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub struct MatchedPath(pub(crate) Arc<str>);

impl MatchedPath {
/// Returns a `str` representation of the path.
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
Expand Down
6 changes: 6 additions & 0 deletions axum/src/extract/multipart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,27 @@ impl Field<'_> {
/// The field name found in the
/// [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
/// header.
#[must_use]
pub fn name(&self) -> Option<&str> {
self.inner.name()
}

/// The file name found in the
/// [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
/// header.
#[must_use]
pub fn file_name(&self) -> Option<&str> {
self.inner.file_name()
}

/// Get the [content type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) of the field.
#[must_use]
pub fn content_type(&self) -> Option<&str> {
self.inner.content_type().map(|m| m.as_ref())
}

/// Get a map of headers as [`HeaderMap`].
#[must_use]
pub fn headers(&self) -> &HeaderMap {
self.inner.headers()
}
Expand Down Expand Up @@ -238,11 +242,13 @@ impl MultipartError {
}

/// Get the response body text used for this rejection.
#[must_use]
pub fn body_text(&self) -> String {
self.source.to_string()
}

/// Get the status code used for this rejection.
#[must_use]
pub fn status(&self) -> http::StatusCode {
status_code_from_multer_error(&self.source)
}
Expand Down
1 change: 1 addition & 0 deletions axum/src/extract/nested_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub struct NestedPath(Arc<str>);

impl NestedPath {
/// Returns a `str` representation of the path.
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
Expand Down
7 changes: 7 additions & 0 deletions axum/src/extract/path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,16 +407,19 @@ pub struct FailedToDeserializePathParams(PathDeserializationError);

impl FailedToDeserializePathParams {
/// Get a reference to the underlying error kind.
#[must_use]
pub fn kind(&self) -> &ErrorKind {
&self.0.kind
}

/// Convert this error into the underlying error kind.
#[must_use]
pub fn into_kind(self) -> ErrorKind {
self.0.kind
}

/// Get the response body text used for this rejection.
#[must_use]
pub fn body_text(&self) -> String {
match self.0.kind {
ErrorKind::Message(_)
Expand All @@ -432,6 +435,7 @@ impl FailedToDeserializePathParams {
}

/// Get the status code used for this rejection.
#[must_use]
pub fn status(&self) -> StatusCode {
match self.0.kind {
ErrorKind::Message(_)
Expand Down Expand Up @@ -523,6 +527,7 @@ where

impl RawPathParams {
/// Get an iterator over the path parameters.
#[must_use]
pub fn iter(&self) -> RawPathParamsIter<'_> {
self.into_iter()
}
Expand Down Expand Up @@ -561,11 +566,13 @@ pub struct InvalidUtf8InPathParam {

impl InvalidUtf8InPathParam {
/// Get the response body text used for this rejection.
#[must_use]
pub fn body_text(&self) -> String {
self.to_string()
}

/// Get the status code used for this rejection.
#[must_use]
pub fn status(&self) -> StatusCode {
StatusCode::BAD_REQUEST
}
Expand Down
1 change: 1 addition & 0 deletions axum/src/extract/ws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ pub struct Utf8Bytes(ts::Utf8Bytes);
impl Utf8Bytes {
/// Creates from a static str.
#[inline]
#[must_use]
pub const fn from_static(str: &'static str) -> Self {
Self(ts::Utf8Bytes::from_static(str))
}
Expand Down
2 changes: 2 additions & 0 deletions axum/src/response/redirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@ impl Redirect {
}

/// Returns the HTTP status code of the `Redirect`.
#[must_use]
pub fn status_code(&self) -> StatusCode {
self.status_code
}

/// Returns the `Redirect`'s URI.
#[must_use]
pub fn location(&self) -> &str {
&self.location
}
Expand Down
1 change: 1 addition & 0 deletions axum/src/routing/method_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ impl MethodFilter {
}

/// Performs the OR operation between the [`MethodFilter`] in `self` with `other`.
#[must_use]
pub const fn or(self, other: Self) -> Self {
Self(self.0 | other.0)
}
Expand Down
2 changes: 2 additions & 0 deletions axum/src/routing/method_routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ impl MethodRouter<(), Infallible> {
/// ```
///
/// [`MakeService`]: tower::make::MakeService
#[must_use]
pub fn into_make_service(self) -> IntoMakeService<Self> {
IntoMakeService::new(self.with_state(()))
}
Expand Down Expand Up @@ -736,6 +737,7 @@ impl MethodRouter<(), Infallible> {
/// [`MakeService`]: tower::make::MakeService
/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
#[cfg(feature = "tokio")]
#[must_use]
pub fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {
IntoMakeServiceWithConnectInfo::new(self.with_state(()))
}
Expand Down
Loading