mirror of
https://github.com/tokio-rs/axum.git
synced 2024-12-28 23:38:20 +01:00
#[must_use]
all the things! (#1809)
This commit is contained in:
parent
5a58edac16
commit
5606ea3f9e
26 changed files with 43 additions and 9 deletions
|
@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
# Unreleased
|
||||
|
||||
- None.
|
||||
- **fixed:** Add `#[must_use]` attributes to types that do nothing unless used ([#1809])
|
||||
|
||||
[#1809]: https://github.com/tokio-rs/axum/pull/1809
|
||||
|
||||
# 0.3.2 (20. January, 2023)
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ use tower_layer::Layer;
|
|||
/// [`RequestExt::with_limited_body`]: crate::RequestExt::with_limited_body
|
||||
/// [`RequestExt::into_limited_body`]: crate::RequestExt::into_limited_body
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub struct DefaultBodyLimit {
|
||||
kind: DefaultBodyLimitKind,
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ use std::fmt;
|
|||
/// }
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
#[must_use]
|
||||
pub struct AppendHeaders<I>(pub I);
|
||||
|
||||
impl<I, K, V> IntoResponse for AppendHeaders<I>
|
||||
|
|
|
@ -9,11 +9,13 @@ and this project adheres to [Semantic Versioning].
|
|||
|
||||
- **added:** Add `Multipart`. This is similar to `axum::extract::Multipart`
|
||||
except that it enforces field exclusivity at runtime instead of compile time,
|
||||
as this improves usability.
|
||||
|
||||
as this improves usability ([#1692])
|
||||
- **added:** Implement `Clone` for `CookieJar`, `PrivateCookieJar` and `SignedCookieJar` ([#1808])
|
||||
- **fixed:** Add `#[must_use]` attributes to types that do nothing unless used ([#1809])
|
||||
|
||||
[#1692]: https://github.com/tokio-rs/axum/pull/1692
|
||||
[#1808]: https://github.com/tokio-rs/axum/pull/1808
|
||||
[#1809]: https://github.com/tokio-rs/axum/pull/1809
|
||||
|
||||
# 0.6.0 (24. February, 2022)
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ pin_project! {
|
|||
/// ```
|
||||
#[cfg(feature = "async-read-body")]
|
||||
#[derive(Debug)]
|
||||
#[must_use]
|
||||
pub struct AsyncReadBody<R> {
|
||||
#[pin]
|
||||
read: StreamBody<ReaderStream<R>>,
|
||||
|
|
|
@ -108,6 +108,7 @@ use tower_service::Service;
|
|||
///
|
||||
/// See the [module docs](self) for examples.
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub enum Either<E1, E2> {
|
||||
#[allow(missing_docs)]
|
||||
E1(E1),
|
||||
|
@ -119,6 +120,7 @@ pub enum Either<E1, E2> {
|
|||
///
|
||||
/// See the [module docs](self) for examples.
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub enum Either3<E1, E2, E3> {
|
||||
#[allow(missing_docs)]
|
||||
E1(E1),
|
||||
|
@ -132,6 +134,7 @@ pub enum Either3<E1, E2, E3> {
|
|||
///
|
||||
/// See the [module docs](self) for examples.
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub enum Either4<E1, E2, E3, E4> {
|
||||
#[allow(missing_docs)]
|
||||
E1(E1),
|
||||
|
@ -147,6 +150,7 @@ pub enum Either4<E1, E2, E3, E4> {
|
|||
///
|
||||
/// See the [module docs](self) for examples.
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub enum Either5<E1, E2, E3, E4, E5> {
|
||||
#[allow(missing_docs)]
|
||||
E1(E1),
|
||||
|
@ -164,6 +168,7 @@ pub enum Either5<E1, E2, E3, E4, E5> {
|
|||
///
|
||||
/// See the [module docs](self) for examples.
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub enum Either6<E1, E2, E3, E4, E5, E6> {
|
||||
#[allow(missing_docs)]
|
||||
E1(E1),
|
||||
|
@ -183,6 +188,7 @@ pub enum Either6<E1, E2, E3, E4, E5, E6> {
|
|||
///
|
||||
/// See the [module docs](self) for examples.
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub enum Either7<E1, E2, E3, E4, E5, E6, E7> {
|
||||
#[allow(missing_docs)]
|
||||
E1(E1),
|
||||
|
@ -204,6 +210,7 @@ pub enum Either7<E1, E2, E3, E4, E5, E6, E7> {
|
|||
///
|
||||
/// See the [module docs](self) for examples.
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub enum Either8<E1, E2, E3, E4, E5, E6, E7, E8> {
|
||||
#[allow(missing_docs)]
|
||||
E1(E1),
|
||||
|
|
|
@ -58,6 +58,7 @@ pin_project! {
|
|||
/// ```
|
||||
// we use `AsExtractor` as the default because you're more likely to name this type if its used
|
||||
// as an extractor
|
||||
#[must_use]
|
||||
pub struct JsonLines<S, T = AsExtractor> {
|
||||
#[pin]
|
||||
inner: Inner<S>,
|
||||
|
|
|
@ -94,6 +94,7 @@ use std::ops::{Deref, DerefMut};
|
|||
/// ```
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "protobuf")))]
|
||||
#[must_use]
|
||||
pub struct Protobuf<T>(pub T);
|
||||
|
||||
#[async_trait]
|
||||
|
|
|
@ -30,6 +30,7 @@ use serde::Serialize;
|
|||
/// ```
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "erased-json")))]
|
||||
#[derive(Debug)]
|
||||
#[must_use]
|
||||
pub struct ErasedJson(serde_json::Result<Bytes>);
|
||||
|
||||
impl ErasedJson {
|
||||
|
|
|
@ -33,6 +33,7 @@ use axum::{
|
|||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
#[must_use]
|
||||
pub struct Resource<S = (), B = Body> {
|
||||
pub(crate) name: String,
|
||||
pub(crate) router: Router<S, B>,
|
||||
|
|
|
@ -7,12 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
# Unreleased
|
||||
|
||||
- **fixed:** Add `#[must_use]` attributes to types that do nothing unless used ([#1809])
|
||||
- **fixed:** Add `#[must_use]` to `WebSocketUpgrade::on_upgrade` ([#1801])
|
||||
- **fixed:** Fix routing issues when loading a `Router` via a dynamic library ([#1806])
|
||||
|
||||
[#1806]: https://github.com/tokio-rs/axum/pull/1806
|
||||
|
||||
[#1801]: https://github.com/tokio-rs/axum/pull/1801
|
||||
[#1806]: https://github.com/tokio-rs/axum/pull/1806
|
||||
[#1809]: https://github.com/tokio-rs/axum/pull/1809
|
||||
|
||||
# 0.6.9 (24. February, 2023)
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ pin_project! {
|
|||
/// ```
|
||||
///
|
||||
/// [`Stream`]: futures_util::stream::Stream
|
||||
#[must_use]
|
||||
pub struct StreamBody<S> {
|
||||
#[pin]
|
||||
stream: SyncWrapper<S>,
|
||||
|
|
|
@ -70,6 +70,7 @@ use tower_service::Service;
|
|||
/// struct Foo(&'static str);
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[must_use]
|
||||
pub struct Extension<T>(pub T);
|
||||
|
||||
#[async_trait]
|
||||
|
|
|
@ -61,6 +61,7 @@ use std::ops::Deref;
|
|||
/// [`Multipart`]: crate::extract::Multipart
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "form")))]
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[must_use]
|
||||
pub struct Form<T>(pub T);
|
||||
|
||||
#[async_trait]
|
||||
|
|
|
@ -97,6 +97,7 @@ use std::ops::{Deref, DerefMut};
|
|||
/// ```
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
|
||||
#[must_use]
|
||||
pub struct Json<T>(pub T);
|
||||
|
||||
#[async_trait]
|
||||
|
|
|
@ -110,6 +110,7 @@ pub fn from_extractor_with_state<E, S>(state: S) -> FromExtractorLayer<E, S> {
|
|||
/// See [`from_extractor`] for more details.
|
||||
///
|
||||
/// [`Layer`]: tower::Layer
|
||||
#[must_use]
|
||||
pub struct FromExtractorLayer<E, S> {
|
||||
state: S,
|
||||
_marker: PhantomData<fn() -> E>,
|
||||
|
|
|
@ -161,6 +161,7 @@ pub fn from_fn_with_state<F, S, T>(state: S, f: F) -> FromFnLayer<F, S, T> {
|
|||
/// [`tower::Layer`] is used to apply middleware to [`Router`](crate::Router)'s.
|
||||
///
|
||||
/// Created with [`from_fn`]. See that function for more details.
|
||||
#[must_use]
|
||||
pub struct FromFnLayer<F, S, T> {
|
||||
f: F,
|
||||
state: S,
|
||||
|
|
|
@ -165,6 +165,7 @@ pub fn map_request_with_state<F, S, T>(state: S, f: F) -> MapRequestLayer<F, S,
|
|||
/// A [`tower::Layer`] from an async function that transforms a request.
|
||||
///
|
||||
/// Created with [`map_request`]. See that function for more details.
|
||||
#[must_use]
|
||||
pub struct MapRequestLayer<F, S, T> {
|
||||
f: F,
|
||||
state: S,
|
||||
|
|
|
@ -149,6 +149,7 @@ pub fn map_response_with_state<F, S, T>(state: S, f: F) -> MapResponseLayer<F, S
|
|||
/// A [`tower::Layer`] from an async function that transforms a response.
|
||||
///
|
||||
/// Created with [`map_response`]. See that function for more details.
|
||||
#[must_use]
|
||||
pub struct MapResponseLayer<F, S, T> {
|
||||
f: F,
|
||||
state: S,
|
||||
|
|
|
@ -39,6 +39,7 @@ pub use sse::Sse;
|
|||
///
|
||||
/// Will automatically get `Content-Type: text/html`.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[must_use]
|
||||
pub struct Html<T>(pub T);
|
||||
|
||||
impl<T> IntoResponse for Html<T>
|
||||
|
@ -98,7 +99,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
Router::<(), Body>::new()
|
||||
_ = Router::<(), Body>::new()
|
||||
.route("/", get(impl_trait_ok))
|
||||
.route("/", get(impl_trait_err))
|
||||
.route("/", get(impl_trait_both))
|
||||
|
@ -208,7 +209,7 @@ mod tests {
|
|||
)
|
||||
}
|
||||
|
||||
Router::<(), Body>::new()
|
||||
_ = Router::<(), Body>::new()
|
||||
.route("/", get(status))
|
||||
.route("/", get(status_headermap))
|
||||
.route("/", get(status_header_array))
|
||||
|
|
|
@ -53,6 +53,7 @@ use tokio::time::Sleep;
|
|||
|
||||
/// An SSE response
|
||||
#[derive(Clone)]
|
||||
#[must_use]
|
||||
pub struct Sse<S> {
|
||||
stream: S,
|
||||
keep_alive: Option<KeepAlive>,
|
||||
|
@ -163,6 +164,7 @@ where
|
|||
|
||||
/// Server-sent event
|
||||
#[derive(Debug, Default, Clone)]
|
||||
#[must_use]
|
||||
pub struct Event {
|
||||
buffer: BytesMut,
|
||||
flags: EventFlags,
|
||||
|
@ -383,6 +385,7 @@ bitflags::bitflags! {
|
|||
/// Configure the interval between keep-alive messages, the content
|
||||
/// of each message, and the associated stream.
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub struct KeepAlive {
|
||||
event: Bytes,
|
||||
max_interval: Duration,
|
||||
|
|
|
@ -513,6 +513,7 @@ where
|
|||
/// S: Service<Request<Body>>,
|
||||
/// {}
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub struct MethodRouter<S = (), B = Body, E = Infallible> {
|
||||
get: MethodEndpoint<S, B, E>,
|
||||
head: MethodEndpoint<S, B, E>,
|
||||
|
|
|
@ -48,6 +48,7 @@ pub use self::method_routing::{
|
|||
pub(crate) struct RouteId(u32);
|
||||
|
||||
/// The router type for composing handlers and services.
|
||||
#[must_use]
|
||||
pub struct Router<S = (), B = Body> {
|
||||
routes: HashMap<RouteId, Endpoint<S, B>>,
|
||||
node: Arc<Node>,
|
||||
|
|
|
@ -522,7 +522,7 @@ fn routes_with_overlapping_method_routes() {
|
|||
fn merging_with_overlapping_method_routes() {
|
||||
async fn handler() {}
|
||||
let app: Router = Router::new().route("/foo/bar", get(handler));
|
||||
app.clone().merge(app);
|
||||
_ = app.clone().merge(app);
|
||||
}
|
||||
|
||||
#[crate::test]
|
||||
|
|
|
@ -257,7 +257,7 @@ async fn multiple_top_level_nests() {
|
|||
#[crate::test]
|
||||
#[should_panic(expected = "Invalid route: nested routes cannot contain wildcards (*)")]
|
||||
async fn nest_cannot_contain_wildcards() {
|
||||
Router::<(), Body>::new().nest("/one/*rest", Router::new());
|
||||
_ = Router::<(), Body>::new().nest("/one/*rest", Router::new());
|
||||
}
|
||||
|
||||
#[crate::test]
|
||||
|
|
|
@ -50,6 +50,7 @@ use std::{convert::Infallible, ops::Deref};
|
|||
/// ```
|
||||
#[cfg(feature = "headers")]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[must_use]
|
||||
pub struct TypedHeader<T>(pub T);
|
||||
|
||||
#[async_trait]
|
||||
|
|
Loading…
Reference in a new issue