mirror of
https://github.com/tokio-rs/axum.git
synced 2024-10-24 01:46:51 +02:00
Improve compile times of handle_error
and check_infallible
(#198)
* Improve compile times of `handle_error` This brings the compile time of the example posted [here][example] from 3 seconds down to 0.3 seconds for me. Having the bounds on the methods does improve UX but not worth sacrificing 10x compile time for. [example]: https://github.com/tokio-rs/axum/issues/145#issue-963183256 * Improve compile time of `check_infallible` * update changelog
This commit is contained in:
parent
93cdfe8c5f
commit
dd0c345040
3 changed files with 39 additions and 22 deletions
|
@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- Overall compile time improvements. If you're having issues with compile time
|
||||||
|
please file an issue!
|
||||||
- Make `FromRequest` default to being generic over `body::Body` ([#146](https://github.com/tokio-rs/axum/pull/146))
|
- Make `FromRequest` default to being generic over `body::Body` ([#146](https://github.com/tokio-rs/axum/pull/146))
|
||||||
- Implement `std::error::Error` for all rejections ([#153](https://github.com/tokio-rs/axum/pull/153))
|
- Implement `std::error::Error` for all rejections ([#153](https://github.com/tokio-rs/axum/pull/153))
|
||||||
- Add `RoutingDsl::or` for combining routes ([#108](https://github.com/tokio-rs/axum/pull/108))
|
- Add `RoutingDsl::or` for combining routes ([#108](https://github.com/tokio-rs/axum/pull/108))
|
||||||
|
@ -39,6 +41,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- `ServiceExt` has been removed and its methods have been moved to `RoutingDsl` ([#160](https://github.com/tokio-rs/axum/pull/160))
|
- `ServiceExt` has been removed and its methods have been moved to `RoutingDsl` ([#160](https://github.com/tokio-rs/axum/pull/160))
|
||||||
- `extractor_middleware` now requires `RequestBody: Default` ([#167](https://github.com/tokio-rs/axum/pull/167))
|
- `extractor_middleware` now requires `RequestBody: Default` ([#167](https://github.com/tokio-rs/axum/pull/167))
|
||||||
- Convert `RequestAlreadyExtracted` to an enum with each possible error variant ([#167](https://github.com/tokio-rs/axum/pull/167))
|
- Convert `RequestAlreadyExtracted` to an enum with each possible error variant ([#167](https://github.com/tokio-rs/axum/pull/167))
|
||||||
|
- `RoutingDsl::check_infallible` now returns a `CheckInfallible` service. This
|
||||||
|
is to improve compile times.
|
||||||
- These future types have been moved
|
- These future types have been moved
|
||||||
- `extract::extractor_middleware::ExtractorMiddlewareResponseFuture` moved
|
- `extract::extractor_middleware::ExtractorMiddlewareResponseFuture` moved
|
||||||
to `extract::extractor_middleware::future::ResponseFuture` ([#133](https://github.com/tokio-rs/axum/pull/133))
|
to `extract::extractor_middleware::future::ResponseFuture` ([#133](https://github.com/tokio-rs/axum/pull/133))
|
||||||
|
|
|
@ -8,7 +8,6 @@ use crate::{
|
||||||
connect_info::{Connected, IntoMakeServiceWithConnectInfo},
|
connect_info::{Connected, IntoMakeServiceWithConnectInfo},
|
||||||
NestedUri,
|
NestedUri,
|
||||||
},
|
},
|
||||||
response::IntoResponse,
|
|
||||||
service::{HandleError, HandleErrorFromRouter},
|
service::{HandleError, HandleErrorFromRouter},
|
||||||
util::ByteStr,
|
util::ByteStr,
|
||||||
};
|
};
|
||||||
|
@ -416,28 +415,18 @@ pub trait RoutingDsl: crate::sealed::Sealed + Sized {
|
||||||
/// # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
/// # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||||
/// # };
|
/// # };
|
||||||
/// ```
|
/// ```
|
||||||
fn handle_error<ReqBody, ResBody, F, Res, E>(
|
fn handle_error<ReqBody, F>(
|
||||||
self,
|
self,
|
||||||
f: F,
|
f: F,
|
||||||
) -> HandleError<Self, F, ReqBody, HandleErrorFromRouter>
|
) -> HandleError<Self, F, ReqBody, HandleErrorFromRouter> {
|
||||||
where
|
|
||||||
Self: Service<Request<ReqBody>, Response = Response<ResBody>>,
|
|
||||||
F: FnOnce(Self::Error) -> Result<Res, E>,
|
|
||||||
Res: IntoResponse,
|
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
|
||||||
ResBody::Error: Into<BoxError> + Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
HandleError::new(self, f)
|
HandleError::new(self, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that your service cannot fail.
|
/// Check that your service cannot fail.
|
||||||
///
|
///
|
||||||
/// That is, its error type is [`Infallible`].
|
/// That is, its error type is [`Infallible`].
|
||||||
fn check_infallible<ReqBody>(self) -> Self
|
fn check_infallible(self) -> CheckInfallible<Self> {
|
||||||
where
|
CheckInfallible(self)
|
||||||
Self: Service<Request<ReqBody>, Error = Infallible>,
|
|
||||||
{
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,6 +953,35 @@ fn strip_prefix(uri: &Uri, prefix: &str) -> Uri {
|
||||||
Uri::from_parts(parts).unwrap()
|
Uri::from_parts(parts).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Middleware that statically verifies that a service cannot fail.
|
||||||
|
///
|
||||||
|
/// Created with [`check_infallible`](RoutingDsl::check_infallible).
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct CheckInfallible<S>(S);
|
||||||
|
|
||||||
|
impl<R, S> Service<R> for CheckInfallible<S>
|
||||||
|
where
|
||||||
|
S: Service<R, Error = Infallible>,
|
||||||
|
{
|
||||||
|
type Response = S::Response;
|
||||||
|
type Error = S::Error;
|
||||||
|
type Future = S::Future;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
self.0.poll_ready(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn call(&mut self, req: R) -> Self::Future {
|
||||||
|
self.0.call(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> RoutingDsl for CheckInfallible<S> {}
|
||||||
|
|
||||||
|
impl<S> crate::sealed::Sealed for CheckInfallible<S> {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -453,15 +453,10 @@ impl<S, F, B> OnMethod<S, F, B> {
|
||||||
/// details.
|
/// details.
|
||||||
///
|
///
|
||||||
/// [`RoutingDsl::handle_error`]: crate::routing::RoutingDsl::handle_error
|
/// [`RoutingDsl::handle_error`]: crate::routing::RoutingDsl::handle_error
|
||||||
pub fn handle_error<ReqBody, H, Res, E>(
|
pub fn handle_error<ReqBody, H>(
|
||||||
self,
|
self,
|
||||||
f: H,
|
f: H,
|
||||||
) -> HandleError<Self, H, ReqBody, HandleErrorFromService>
|
) -> HandleError<Self, H, ReqBody, HandleErrorFromService> {
|
||||||
where
|
|
||||||
Self: Service<Request<ReqBody>, Response = Response<BoxBody>>,
|
|
||||||
H: FnOnce(<Self as Service<Request<ReqBody>>>::Error) -> Result<Res, E>,
|
|
||||||
Res: IntoResponse,
|
|
||||||
{
|
|
||||||
HandleError::new(self, f)
|
HandleError::new(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue