Fixes for the SegmentTrie

This commit is contained in:
Tommi Reiman 2019-01-15 22:13:12 +02:00
parent 433cf9102d
commit b8d8286265
2 changed files with 28 additions and 10 deletions

View file

@ -52,7 +52,7 @@ public class SegmentTrie {
private Map<String, SegmentTrie> childs = new HashMap<>();
private Map<Keyword, SegmentTrie> wilds = new HashMap<>();
private Keyword catchAll = null;
private Map<Keyword, SegmentTrie> 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());

View file

@ -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")))))