diff --git a/axum/src/response/mod.rs b/axum/src/response/mod.rs index 9655ddc8..b8d5e9e5 100644 --- a/axum/src/response/mod.rs +++ b/axum/src/response/mod.rs @@ -93,7 +93,7 @@ mod tests { } } - Router::<(), Body, _>::new() + Router::<()>::new() .route("/", get(impl_trait_ok)) .route("/", get(impl_trait_err)) .route("/", get(impl_trait_both)) @@ -203,7 +203,7 @@ mod tests { ) } - Router::<(), Body, _>::new() + Router::<()>::new() .route("/", get(status)) .route("/", get(status_headermap)) .route("/", get(status_header_array)) diff --git a/axum/src/routing/method_routing.rs b/axum/src/routing/method_routing.rs index e9cf34cf..a8856ec2 100644 --- a/axum/src/routing/method_routing.rs +++ b/axum/src/routing/method_routing.rs @@ -491,6 +491,7 @@ where /// A [`Service`] that accepts requests based on a [`MethodFilter`] and /// allows chaining additional handlers and services. // TODO(david): Bring back `B = Body, E = Infallible` defaults +// TODO(david): think about ordering of type params here pub struct MethodRouter { // Invariant: If `R == MissingState` then `state` is `None` // If `R == WithState` then state is `Some` diff --git a/axum/src/routing/mod.rs b/axum/src/routing/mod.rs index 704a58b4..f2055d71 100644 --- a/axum/src/routing/mod.rs +++ b/axum/src/routing/mod.rs @@ -64,18 +64,18 @@ impl RouteId { } /// The router type for composing handlers and services. -pub struct Router { +pub struct Router { // Invariant: If `R == MissingState` then `state` is `None` // If `R == WithState` then state is `Some` // `R` cannot have other values state: Option, - routes: HashMap>, + routes: HashMap>, node: Arc, fallback: Fallback, _marker: PhantomData, } -impl Clone for Router +impl Clone for Router where S: Clone, { @@ -90,7 +90,7 @@ where } } -impl Default for Router +impl Default for Router where B: HttpBody + Send + 'static, { @@ -99,7 +99,7 @@ where } } -impl fmt::Debug for Router +impl fmt::Debug for Router where S: fmt::Debug, { @@ -123,7 +123,7 @@ where pub(crate) const NEST_TAIL_PARAM: &str = "__private__axum_nest_tail_param"; const NEST_TAIL_PARAM_CAPTURE: &str = "/*__private__axum_nest_tail_param"; -impl Router +impl Router where B: HttpBody + Send + 'static, { @@ -141,7 +141,7 @@ where } } - fn state(self, state: S) -> Router + fn state(self, state: S) -> Router where S: Clone, { @@ -171,11 +171,11 @@ where } } -impl Router +impl Router where B: HttpBody + Send + 'static, { - pub fn map_state(self, f: F) -> Router + pub fn map_state(self, f: F) -> Router where F: Fn(OuterState) -> InnerState + Clone + Send + Sync + 'static, OuterState: Clone + Send + Sync + 'static, @@ -229,7 +229,7 @@ where } } -impl Router +impl Router where B: HttpBody + Send + 'static, S: Clone, @@ -240,7 +240,7 @@ where } } -impl Router<(), B, WithState> +impl Router<(), WithState, B> where B: HttpBody + Send + 'static, { @@ -250,7 +250,7 @@ where } } -impl Router +impl Router where B: HttpBody + Send + 'static, S: Clone + 'static, @@ -307,7 +307,7 @@ where T: Service, Response = Response, Error = Infallible> + Clone + Send + 'static, T::Future: Send + 'static, { - let service = match try_downcast::, _>(service) { + let service = match try_downcast::, _>(service) { Ok(_) => { panic!("Invalid route: `Router::route` cannot be used with `Router`s. Use `Router::nest` instead") } @@ -324,7 +324,7 @@ where self } - fn insert_endpoint(&mut self, path: &str, id: RouteId, endpoint: Endpoint) { + fn insert_endpoint(&mut self, path: &str, id: RouteId, endpoint: Endpoint) { let mut node = Arc::try_unwrap(Arc::clone(&self.node)).unwrap_or_else(|node| (*node).clone()); if let Err(err) = node.insert(path, id) { @@ -336,7 +336,7 @@ where } #[doc = include_str!("../docs/routing/nest.md")] - pub fn nest(mut self, mut path: &str, router: Router) -> Self { + pub fn nest(mut self, mut path: &str, router: Router) -> Self { validate_path_for_nest(&mut path); let prefix = path; @@ -414,7 +414,7 @@ where #[doc = include_str!("../docs/routing/merge.md")] pub fn merge(mut self, other: R2) -> Self where - R2: Into>, + R2: Into>, { let Router { state, @@ -450,7 +450,7 @@ where } #[doc = include_str!("../docs/routing/layer.md")] - pub fn layer(self, layer: L) -> Router + pub fn layer(self, layer: L) -> Router where L: Layer>, L::Service: @@ -551,7 +551,7 @@ where } } -impl Router +impl Router where B: HttpBody + Send + 'static, S: Clone + Send + Sync + 'static, @@ -636,7 +636,7 @@ where } } -impl Service> for Router +impl Service> for Router where B: HttpBody + Send + 'static, S: Clone + Send + Sync + 'static, @@ -785,12 +785,12 @@ impl Fallback { } } -enum Endpoint { +enum Endpoint { MethodRouter(MethodRouter), Route(Route), } -impl Clone for Endpoint +impl Clone for Endpoint where S: Clone, { @@ -802,7 +802,7 @@ where } } -impl fmt::Debug for Endpoint +impl fmt::Debug for Endpoint where S: fmt::Debug, { @@ -821,3 +821,14 @@ fn traits() { assert_send::>(); assert_send::>(); } + +/// ```compile_fail +/// use axum::{Router, routing::get, extract::State}; +/// +/// async fn handler(_: State) {} +/// +/// let app = Router::without_state().route("/", get(handler)); +/// # let _: Router<(), axum::routing::WithState> = app; +/// ``` +#[allow(dead_code)] +fn extracting_wrong_state_type_doesnt_compile() {} diff --git a/axum/src/routing/tests/mod.rs b/axum/src/routing/tests/mod.rs index a00a5b7f..37c6dcd7 100644 --- a/axum/src/routing/tests/mod.rs +++ b/axum/src/routing/tests/mod.rs @@ -695,8 +695,3 @@ async fn extracting_state() { let res = client.get("/").send().await; assert_eq!(res.text().await, "foo"); } - -#[tokio::test] -async fn extracting_wrong_state_type_doesnt_compile() { - todo!() -} diff --git a/axum/src/routing/tests/nest.rs b/axum/src/routing/tests/nest.rs index 54f3dc05..9998837e 100644 --- a/axum/src/routing/tests/nest.rs +++ b/axum/src/routing/tests/nest.rs @@ -297,7 +297,7 @@ async fn multiple_top_level_nests() { #[tokio::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::<()>::new().nest("/one/*rest", Router::new()); } #[tokio::test]