mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-01 00:00:14 +02:00
checkpoint
This commit is contained in:
@@ -12,51 +12,59 @@ use tower_service::Service;
|
|||||||
/// An adapter that makes a [`Handler`] into a [`Service`].
|
/// An adapter that makes a [`Handler`] into a [`Service`].
|
||||||
///
|
///
|
||||||
/// Created with [`Handler::into_service`].
|
/// Created with [`Handler::into_service`].
|
||||||
pub struct IntoService<H, T, B> {
|
pub struct IntoService<H, S, T, B> {
|
||||||
handler: H,
|
handler: H,
|
||||||
|
state: S,
|
||||||
_marker: PhantomData<fn() -> (T, B)>,
|
_marker: PhantomData<fn() -> (T, B)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn traits() {
|
fn traits() {
|
||||||
use crate::test_helpers::*;
|
use crate::test_helpers::*;
|
||||||
assert_send::<IntoService<(), NotSendSync, NotSendSync>>();
|
assert_send::<IntoService<(), (), NotSendSync, NotSendSync>>();
|
||||||
assert_sync::<IntoService<(), NotSendSync, NotSendSync>>();
|
assert_sync::<IntoService<(), (), NotSendSync, NotSendSync>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, T, B> IntoService<H, T, B> {
|
impl<H, S, T, B> IntoService<H, S, T, B> {
|
||||||
pub(super) fn new(handler: H) -> Self {
|
pub(super) fn new(handler: H, state: S) -> Self {
|
||||||
Self {
|
Self {
|
||||||
handler,
|
handler,
|
||||||
|
state,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, T, B> fmt::Debug for IntoService<H, T, B> {
|
impl<H, S, T, B> fmt::Debug for IntoService<H, S, T, B>
|
||||||
|
where
|
||||||
|
S: fmt::Debug,
|
||||||
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_tuple("IntoService")
|
f.debug_struct("IntoService")
|
||||||
.field(&format_args!("..."))
|
.field("state", &self.state)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, T, B> Clone for IntoService<H, T, B>
|
impl<H, S, T, B> Clone for IntoService<H, S, T, B>
|
||||||
where
|
where
|
||||||
H: Clone,
|
H: Clone,
|
||||||
|
S: Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
handler: self.handler.clone(),
|
handler: self.handler.clone(),
|
||||||
|
state: self.state.clone(),
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, T, B> Service<Request<B>> for IntoService<H, T, B>
|
impl<H, S, T, B> Service<Request<B>> for IntoService<H, S, T, B>
|
||||||
where
|
where
|
||||||
H: Handler<T, B> + Clone + Send + 'static,
|
H: Handler<S, T, B> + Clone + Send + 'static,
|
||||||
B: Send + 'static,
|
B: Send + 'static,
|
||||||
|
S: Clone,
|
||||||
{
|
{
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
@@ -74,7 +82,8 @@ where
|
|||||||
use futures_util::future::FutureExt;
|
use futures_util::future::FutureExt;
|
||||||
|
|
||||||
let handler = self.handler.clone();
|
let handler = self.handler.clone();
|
||||||
let future = Handler::call(handler, req);
|
let state = self.state.clone();
|
||||||
|
let future = Handler::call(handler, state, req);
|
||||||
let future = future.map(Ok as _);
|
let future = future.map(Ok as _);
|
||||||
|
|
||||||
super::future::IntoServiceFuture::new(future)
|
super::future::IntoServiceFuture::new(future)
|
||||||
|
|||||||
+20
-17
@@ -61,12 +61,12 @@ pub use self::into_service::IntoService;
|
|||||||
/// See the [module docs](crate::handler) for more details.
|
/// See the [module docs](crate::handler) for more details.
|
||||||
///
|
///
|
||||||
#[doc = include_str!("../docs/debugging_handler_type_errors.md")]
|
#[doc = include_str!("../docs/debugging_handler_type_errors.md")]
|
||||||
pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {
|
pub trait Handler<S, T, B = Body>: Clone + Send + Sized + 'static {
|
||||||
/// The type of future calling this handler returns.
|
/// The type of future calling this handler returns.
|
||||||
type Future: Future<Output = Response> + Send + 'static;
|
type Future: Future<Output = Response> + Send + 'static;
|
||||||
|
|
||||||
/// Call the handler with the given request.
|
/// Call the handler with the given request.
|
||||||
fn call(self, req: Request<B>) -> Self::Future;
|
fn call(self, state: S, req: Request<B>) -> Self::Future;
|
||||||
|
|
||||||
/// Apply a [`tower::Layer`] to the handler.
|
/// Apply a [`tower::Layer`] to the handler.
|
||||||
///
|
///
|
||||||
@@ -106,9 +106,11 @@ pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {
|
|||||||
/// ```
|
/// ```
|
||||||
fn layer<L>(self, layer: L) -> Layered<L::Service, T>
|
fn layer<L>(self, layer: L) -> Layered<L::Service, T>
|
||||||
where
|
where
|
||||||
L: Layer<IntoService<Self, T, B>>,
|
L: Layer<IntoService<Self, S, T, B>>,
|
||||||
{
|
{
|
||||||
Layered::new(layer.layer(self.into_service()))
|
// TODO(david): write this, somehow
|
||||||
|
todo!()
|
||||||
|
// Layered::new(layer.layer(self.into_service()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the handler into a [`Service`].
|
/// Convert the handler into a [`Service`].
|
||||||
@@ -143,8 +145,8 @@ pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`Router::fallback`]: crate::routing::Router::fallback
|
/// [`Router::fallback`]: crate::routing::Router::fallback
|
||||||
fn into_service(self) -> IntoService<Self, T, B> {
|
fn into_service(self, state: S) -> IntoService<Self, S, T, B> {
|
||||||
IntoService::new(self)
|
IntoService::new(self, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the handler into a [`MakeService`].
|
/// Convert the handler into a [`MakeService`].
|
||||||
@@ -170,8 +172,8 @@ pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`MakeService`]: tower::make::MakeService
|
/// [`MakeService`]: tower::make::MakeService
|
||||||
fn into_make_service(self) -> IntoMakeService<IntoService<Self, T, B>> {
|
fn into_make_service(self, state: S) -> IntoMakeService<IntoService<Self, S, T, B>> {
|
||||||
IntoMakeService::new(self.into_service())
|
IntoMakeService::new(self.into_service(state))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the handler into a [`MakeService`] which stores information
|
/// Convert the handler into a [`MakeService`] which stores information
|
||||||
@@ -204,12 +206,13 @@ pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {
|
|||||||
/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
||||||
fn into_make_service_with_connect_info<C>(
|
fn into_make_service_with_connect_info<C>(
|
||||||
self,
|
self,
|
||||||
) -> IntoMakeServiceWithConnectInfo<IntoService<Self, T, B>, C> {
|
state: S,
|
||||||
IntoMakeServiceWithConnectInfo::new(self.into_service())
|
) -> IntoMakeServiceWithConnectInfo<IntoService<Self, S, T, B>, C> {
|
||||||
|
IntoMakeServiceWithConnectInfo::new(self.into_service(state))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Res, B> Handler<(), B> for F
|
impl<F, Fut, Res, B, S> Handler<S, (), B> for F
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Fut + Clone + Send + 'static,
|
F: FnOnce() -> Fut + Clone + Send + 'static,
|
||||||
Fut: Future<Output = Res> + Send,
|
Fut: Future<Output = Res> + Send,
|
||||||
@@ -218,7 +221,7 @@ where
|
|||||||
{
|
{
|
||||||
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
|
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
|
||||||
|
|
||||||
fn call(self, _req: Request<B>) -> Self::Future {
|
fn call(self, _state: S, _req: Request<B>) -> Self::Future {
|
||||||
Box::pin(async move { self().await.into_response() })
|
Box::pin(async move { self().await.into_response() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,7 +229,7 @@ where
|
|||||||
macro_rules! impl_handler {
|
macro_rules! impl_handler {
|
||||||
( $($ty:ident),* $(,)? ) => {
|
( $($ty:ident),* $(,)? ) => {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
impl<F, Fut, B, Res, $($ty,)*> Handler<($($ty,)*), B> for F
|
impl<F, Fut, B, Res, S, $($ty,)*> Handler<S, ($($ty,)*), B> for F
|
||||||
where
|
where
|
||||||
F: FnOnce($($ty,)*) -> Fut + Clone + Send + 'static,
|
F: FnOnce($($ty,)*) -> Fut + Clone + Send + 'static,
|
||||||
Fut: Future<Output = Res> + Send,
|
Fut: Future<Output = Res> + Send,
|
||||||
@@ -236,7 +239,7 @@ macro_rules! impl_handler {
|
|||||||
{
|
{
|
||||||
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
|
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
|
||||||
|
|
||||||
fn call(self, req: Request<B>) -> Self::Future {
|
fn call(self, state: S, req: Request<B>) -> Self::Future {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let mut req = RequestParts::new(req);
|
let mut req = RequestParts::new(req);
|
||||||
|
|
||||||
@@ -284,7 +287,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, T, ReqBody, ResBody> Handler<T, ReqBody> for Layered<S, T>
|
impl<S, T, ReqBody, ResBody, St> Handler<St, T, ReqBody> for Layered<S, T>
|
||||||
where
|
where
|
||||||
S: Service<Request<ReqBody>, Response = Response<ResBody>> + Clone + Send + 'static,
|
S: Service<Request<ReqBody>, Response = Response<ResBody>> + Clone + Send + 'static,
|
||||||
S::Error: IntoResponse,
|
S::Error: IntoResponse,
|
||||||
@@ -296,7 +299,7 @@ where
|
|||||||
{
|
{
|
||||||
type Future = future::LayeredFuture<S, ReqBody>;
|
type Future = future::LayeredFuture<S, ReqBody>;
|
||||||
|
|
||||||
fn call(self, req: Request<ReqBody>) -> Self::Future {
|
fn call(self, state: St, req: Request<ReqBody>) -> Self::Future {
|
||||||
use futures_util::future::{FutureExt, Map};
|
use futures_util::future::{FutureExt, Map};
|
||||||
|
|
||||||
let future: Map<_, fn(Result<S::Response, S::Error>) -> _> =
|
let future: Map<_, fn(Result<S::Response, S::Error>) -> _> =
|
||||||
@@ -330,7 +333,7 @@ mod tests {
|
|||||||
format!("you said: {}", body)
|
format!("you said: {}", body)
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = TestClient::new(handle.into_service());
|
let client = TestClient::new(handle.into_service(()));
|
||||||
|
|
||||||
let res = client.post("/").body("hi there!").send().await;
|
let res = client.post("/").body("hi there!").send().await;
|
||||||
assert_eq!(res.status(), StatusCode::OK);
|
assert_eq!(res.status(), StatusCode::OK);
|
||||||
|
|||||||
Reference in New Issue
Block a user