diff --git a/modules/reitit-core/java-src/reitit/SegmentTrie.java b/modules/reitit-core/java-src/reitit/SegmentTrie.java index 77422d6e..2337d893 100644 --- a/modules/reitit-core/java-src/reitit/SegmentTrie.java +++ b/modules/reitit-core/java-src/reitit/SegmentTrie.java @@ -52,7 +52,7 @@ public class SegmentTrie { private Map childs = new HashMap<>(); private Map wilds = new HashMap<>(); - private Keyword catchAll = null; + private Map catchAll = new HashMap<>(); private Object data; public SegmentTrie add(String path, Object data) { @@ -68,7 +68,13 @@ public class SegmentTrie { } pointer = s; } else if (p.startsWith("*")) { - pointer.catchAll = Keyword.intern(p.substring(1)); + Keyword k = Keyword.intern(p.substring(1)); + SegmentTrie s = pointer.catchAll.get(k); + if (s == null) { + s = new SegmentTrie(); + pointer.catchAll.put(k, s); + } + pointer = s; break; } else { SegmentTrie s = pointer.childs.get(p); @@ -97,8 +103,11 @@ public class SegmentTrie { public Matcher matcher() { Matcher m; - if (catchAll != null) { - m = new CatchAllMatcher(catchAll, data); + if (!catchAll.isEmpty()) { + m = new CatchAllMatcher(catchAll.keySet().iterator().next(), catchAll.values().iterator().next().data); + if (data != null) { + m = new LinearMatcher(Arrays.asList(new DataMatcher(data), m)); + } } else if (!wilds.isEmpty()) { if (wilds.size() == 1 && data == null && childs.isEmpty()) { m = new WildMatcher(wilds.keySet().iterator().next(), wilds.values().iterator().next().matcher()); diff --git a/test/cljc/reitit/segment_test.cljc b/test/cljc/reitit/segment_test.cljc index 696e44ba..ca7bd2bf 100644 --- a/test/cljc/reitit/segment_test.cljc +++ b/test/cljc/reitit/segment_test.cljc @@ -2,11 +2,20 @@ (:require [clojure.test :refer [deftest testing is are]] [reitit.segment :as s])) -(-> (s/insert nil "/foo" {:a 1}) (s/compile) (s/lookup "/foo")) -; => #reitit.segment.Match{:data {:a 1}, :path-params {}} +(deftest tests + (is (= (s/->Match {:a 1} {}) + (-> (s/insert nil "/foo" {:a 1}) + (s/compile) + (s/lookup "/foo")))) -(-> (s/insert nil "/foo" {:a 1}) (s/insert "/foo/*" {:b 1}) (s/compile) (s/lookup "/foo")) -; => nil + (is (= (s/->Match {:a 1} {}) + (-> (s/insert nil "/foo" {:a 1}) + (s/insert "/foo/*bar" {:b 1}) + (s/compile) + (s/lookup "/foo")))) -(-> (s/insert nil "/foo" {:a 1}) (s/insert "/foo/*" {:b 1}) (s/compile) (s/lookup "/foo/bar")) -; => #reitit.segment.Match{:data {:b 1}, :path-params {: "bar"}} + (is (= (s/->Match {:b 1} {:bar "bar"}) + (-> (s/insert nil "/foo" {:a 1}) + (s/insert "/foo/*bar" {:b 1}) + (s/compile) + (s/lookup "/foo/bar")))))