Implement Deref and DerefMut for built-in extractors (#1922)

This commit is contained in:
David Pedersen
2023-04-10 07:18:35 +00:00
committed by GitHub
parent 43b2d52403
commit 352cf9a266
17 changed files with 67 additions and 112 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ license = "MIT"
name = "axum-core"
readme = "README.md"
repository = "https://github.com/tokio-rs/axum"
version = "0.3.3" # remember to also bump the version that axum depends on
version = "0.3.3" # remember to also bump the version that axum and axum-extra depends on
[features]
__private_docs = ["dep:tower-http"]
+41
View File
@@ -171,3 +171,44 @@ macro_rules! all_the_tuples_no_last_special_case {
$name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);
};
}
/// Private API.
#[doc(hidden)]
#[macro_export]
macro_rules! __impl_deref {
($ident:ident) => {
impl<T> std::ops::Deref for $ident<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> std::ops::DerefMut for $ident<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
};
($ident:ident: $ty:ty) => {
impl std::ops::Deref for $ident {
type Target = $ty;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::DerefMut for $ident {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
};
}
+2
View File
@@ -7,9 +7,11 @@ and this project adheres to [Semantic Versioning].
# Unreleased
- **added:** Implement `Deref` and `DerefMut` for built-in extractors ([#1922])
- **added:** Add `OptionalPath` extractor ([#1889])
[#1889]: https://github.com/tokio-rs/axum/pull/1889
[#1922]: https://github.com/tokio-rs/axum/pull/1922
# 0.7.2 (22. March, 2023)
+1
View File
@@ -35,6 +35,7 @@ typed-routing = ["dep:axum-macros", "dep:percent-encoding", "dep:serde_html_form
[dependencies]
axum = { path = "../axum", version = "0.6.9", default-features = false }
axum-core = { path = "../axum-core", version = "0.3.3" }
bytes = "1.1.0"
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
http = "0.2"
+1 -14
View File
@@ -3,7 +3,6 @@ use axum::{
extract::{Extension, FromRequestParts},
};
use http::request::Parts;
use std::ops::{Deref, DerefMut};
/// Cache results of other extractors.
///
@@ -108,19 +107,7 @@ where
}
}
impl<T> Deref for Cached<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Cached<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
axum_core::__impl_deref!(Cached);
#[cfg(test)]
mod tests {
+2 -8
View File
@@ -7,7 +7,7 @@ use axum::{
};
use http::{Request, StatusCode};
use serde::de::DeserializeOwned;
use std::{fmt, ops::Deref};
use std::fmt;
/// Extractor that deserializes `application/x-www-form-urlencoded` requests
/// into some type.
@@ -43,13 +43,7 @@ use std::{fmt, ops::Deref};
#[cfg(feature = "form")]
pub struct Form<T>(pub T);
impl<T> Deref for Form<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
axum_core::__impl_deref!(Form);
#[async_trait]
impl<T, S, B> FromRequest<S, B> for Form<T>
+2 -8
View File
@@ -6,7 +6,7 @@ use axum::{
};
use http::{request::Parts, StatusCode};
use serde::de::DeserializeOwned;
use std::{fmt, ops::Deref};
use std::fmt;
/// Extractor that deserializes query strings into some type.
///
@@ -73,13 +73,7 @@ where
}
}
impl<T> Deref for Query<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
axum_core::__impl_deref!(Query);
/// Rejection used for [`Query`].
///
+1 -14
View File
@@ -10,7 +10,6 @@ use axum::{
use bytes::BytesMut;
use http::{Request, StatusCode};
use prost::Message;
use std::ops::{Deref, DerefMut};
/// A Protocol Buffer message extractor and response.
///
@@ -118,19 +117,7 @@ where
}
}
impl<T> Deref for Protobuf<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Protobuf<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
axum_core::__impl_deref!(Protobuf);
impl<T> From<T> for Protobuf<T> {
fn from(inner: T) -> Self {
+1 -1
View File
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
# Unreleased
- None.
- **added:** Implement `Deref` and `DerefMut` for built-in extractors
# 0.6.12 (22. March, 2023)
+1 -8
View File
@@ -7,7 +7,6 @@ use axum_core::{
use http::{request::Parts, Request};
use std::{
convert::Infallible,
ops::Deref,
task::{Context, Poll},
};
use tower_service::Service;
@@ -97,13 +96,7 @@ where
}
}
impl<T> Deref for Extension<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
axum_core::__impl_deref!(Extension);
impl<T> IntoResponseParts for Extension<T>
where
+2
View File
@@ -147,6 +147,8 @@ where
}
}
axum_core::__impl_deref!(ConnectInfo);
/// Middleware used to mock [`ConnectInfo`] during tests.
///
/// If you're accidentally using [`MockConnectInfo`] and
+2 -20
View File
@@ -12,11 +12,7 @@ use async_trait::async_trait;
use axum_core::response::{IntoResponse, Response};
use http::{request::Parts, StatusCode};
use serde::de::DeserializeOwned;
use std::{
fmt,
ops::{Deref, DerefMut},
sync::Arc,
};
use std::{fmt, sync::Arc};
/// Extractor that will get captures from the URL and parse them using
/// [`serde`].
@@ -152,21 +148,7 @@ use std::{
#[derive(Debug)]
pub struct Path<T>(pub T);
impl<T> Deref for Path<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Path<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
axum_core::__impl_deref!(Path);
#[async_trait]
impl<T, S> FromRequestParts<S> for Path<T>
+1 -8
View File
@@ -2,7 +2,6 @@ use super::{rejection::*, FromRequestParts};
use async_trait::async_trait;
use http::request::Parts;
use serde::de::DeserializeOwned;
use std::ops::Deref;
/// Extractor that deserializes query strings into some type.
///
@@ -65,13 +64,7 @@ where
}
}
impl<T> Deref for Query<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
axum_core::__impl_deref!(Query);
#[cfg(test)]
mod tests {
+5
View File
@@ -101,6 +101,9 @@ where
}
}
#[cfg(feature = "original-uri")]
axum_core::__impl_deref!(OriginalUri: Uri);
/// Extractor that extracts the request body as a [`Stream`].
///
/// Since extracting the request body requires consuming it, the `BodyStream` extractor must be
@@ -221,6 +224,8 @@ where
}
}
axum_core::__impl_deref!(RawBody);
#[cfg(test)]
mod tests {
use crate::{extract::Extension, routing::get, test_helpers::*, Router};
+1 -8
View File
@@ -8,7 +8,6 @@ use http::header::CONTENT_TYPE;
use http::{Request, StatusCode};
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::ops::Deref;
/// URL encoded extractor and response.
///
@@ -115,13 +114,7 @@ where
}
}
impl<T> Deref for Form<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
axum_core::__impl_deref!(Form);
#[cfg(test)]
mod tests {
+1 -14
View File
@@ -11,7 +11,6 @@ use http::{
Request, StatusCode,
};
use serde::{de::DeserializeOwned, Serialize};
use std::ops::{Deref, DerefMut};
/// JSON Extractor / Response.
///
@@ -170,19 +169,7 @@ fn json_content_type(headers: &HeaderMap) -> bool {
is_json_content_type
}
impl<T> Deref for Json<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Json<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
axum_core::__impl_deref!(Json);
impl<T> From<T> for Json<T> {
fn from(inner: T) -> Self {
+2 -8
View File
@@ -3,7 +3,7 @@ use async_trait::async_trait;
use axum_core::response::{IntoResponse, IntoResponseParts, Response, ResponseParts};
use headers::HeaderMapExt;
use http::request::Parts;
use std::{convert::Infallible, ops::Deref};
use std::convert::Infallible;
/// Extractor and response that works with typed header values from [`headers`].
///
@@ -78,13 +78,7 @@ where
}
}
impl<T> Deref for TypedHeader<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
axum_core::__impl_deref!(TypedHeader);
impl<T> IntoResponseParts for TypedHeader<T>
where