From 9b17d86b92006d39e6c97acb80206c4e010c3f91 Mon Sep 17 00:00:00 2001
From: David Pedersen <david.pdrsn@gmail.com>
Date: Tue, 26 Oct 2021 01:35:33 +0200
Subject: [PATCH] Update to matchit 0.4.4 (#417)

- Static vs dynamic paths are now supported meaning `/foo` and `/:key`
  are not considered to overlap.
- A bug we hit regarding trailing slashes is fixed.
---
 CHANGELOG.md       |  2 --
 Cargo.toml         |  2 +-
 src/routing/mod.rs | 18 +-----------------
 src/tests/mod.rs   | 18 ++++++++++++++++++
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c7f7703b..900f1eb4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -41,8 +41,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
     - **fixed:** Adding a conflicting route will now cause a panic instead of silently making
       a route unreachable.
     - **fixed:** Route matching is faster as number of routes increase.
-    - **breaking:** The routes `/foo` and `/:key` are considered to overlap and
-      will cause a panic when constructing the router. This might be fixed in the future.
   - **fixed:** Middleware that return early (such as `tower_http::auth::RequireAuthorization`)
     now no longer catch requests that would otherwise be 404s. They also work
     correctly with `Router::merge` (previously called `or`) ([#408])
diff --git a/Cargo.toml b/Cargo.toml
index ecd331b6..032b263e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,7 +31,7 @@ futures-util = { version = "0.3", default-features = false, features = ["alloc"]
 http = "0.2"
 http-body = "0.4.3"
 hyper = { version = "0.14", features = ["server", "tcp", "stream"] }
-matchit = "0.4"
+matchit = "0.4.4"
 percent-encoding = "2.1"
 pin-project-lite = "0.2.7"
 serde = "1.0"
diff --git a/src/routing/mod.rs b/src/routing/mod.rs
index 7f027f36..53250a6d 100644
--- a/src/routing/mod.rs
+++ b/src/routing/mod.rs
@@ -178,19 +178,6 @@ where
     /// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
     /// # };
     /// ```
-    ///
-    /// Note that routes like `/:key` and `/foo` are considered overlapping:
-    ///
-    /// ```should_panic
-    /// use axum::{routing::get, Router};
-    ///
-    /// let app = Router::new()
-    ///     .route("/foo", get(|| async {}))
-    ///     .route("/:key", get(|| async {}));
-    /// # async {
-    /// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
-    /// # };
-    /// ```
     pub fn route<T>(mut self, path: &str, svc: T) -> Self
     where
         T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible>
@@ -793,10 +780,7 @@ where
         match self.node.at(&path) {
             Ok(match_) => self.call_route(match_, req),
             Err(err) => {
-                if err.tsr()
-                    // workaround for https://github.com/ibraheemdev/matchit/issues/7
-                    && path != "/"
-                {
+                if err.tsr() {
                     let redirect_to = if let Some(without_tsr) = path.strip_suffix('/') {
                         with_path(req.uri(), without_tsr)
                     } else {
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index b7513cf6..da6c5a64 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -640,6 +640,24 @@ async fn access_matched_path() {
     assert_eq!(res.text().await, "/:key");
 }
 
+#[tokio::test]
+async fn static_and_dynamic_paths() {
+    let app = Router::new()
+        .route(
+            "/:key",
+            get(|Path(key): Path<String>| async move { format!("dynamic: {}", key) }),
+        )
+        .route("/foo", get(|| async { "static" }));
+
+    let client = TestClient::new(app);
+
+    let res = client.get("/bar").send().await;
+    assert_eq!(res.text().await, "dynamic: bar");
+
+    let res = client.get("/foo").send().await;
+    assert_eq!(res.text().await, "static");
+}
+
 pub(crate) fn assert_send<T: Send>() {}
 pub(crate) fn assert_sync<T: Sync>() {}
 pub(crate) fn assert_unpin<T: Unpin>() {}