Skip to content

Commit f9daafa

Browse files
committed
Unbreak inline :or matching.
1 parent 02dba34 commit f9daafa

File tree

2 files changed

+89
-44
lines changed

2 files changed

+89
-44
lines changed

src/active/clojure/match.clj

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@
315315
[& exclusions]
316316
(complement (apply some-fn exclusions)))
317317

318-
319318
(s/def ::regex regex?)
320319
(s/def ::compare-fn-token #{:compare-fn})
321320
(s/def ::fn? any?)
@@ -347,7 +346,7 @@
347346

348347
(s/def ::path-exists-without-binding
349348
(s/or :flat ::path
350-
:list (s/cat :path ::path)))
349+
:list (s/cat :path ::path)))
351350

352351
(s/def ::path-exists-with-binding
353352
(s/cat :path ::path :binding-key ::binding-key :binding ::binding))
@@ -484,7 +483,7 @@
484483
:optional-path-with-default-binding
485484
(let [path (mapv make-key (:path body))
486485
b (make-binding (:binding body))]
487-
`(optional-path-with-default-binding-clause ~path ~(:default-value body) ~b)))))))
486+
`(optional-path-with-default-binding-clause ~path ~(:default-value body) ~b)))))))
488487

489488
(defmacro parse-clauses
490489
[cs]
@@ -550,12 +549,15 @@
550549
:key-matches-without-binding
551550
(let [k (make-key (:key body))
552551
match (:match-value body)
553-
predicate? (= :compare-fn (first match))
552+
match-kind (first match)
554553
match-value (second match)]
555554
(cond
556-
predicate?
555+
(= :compare-fn match-kind)
557556
[`({~k ~'_} :guard [(constantly (~(:fn match-value) (get-in ~message [~k])))])
558557
`[]]
558+
(= :options match-kind)
559+
[`{~k (:or ~@(:options match-value))}
560+
`[]]
559561
:else
560562
[`{~k ~match-value}
561563
`[]]))
@@ -564,46 +566,54 @@
564566
(let [k (make-key (:key body))
565567
b (make-binding (:binding body))
566568
match (:match-value body)
567-
predicate? (= :compare-fn (first match))
569+
match-kind (first match)
568570
match-value (second match)]
569571
(cond
570-
predicate?
572+
(= :compare-fn match-kind)
571573
[`({~k ~'_} :guard [(constantly (~(:fn match-value) (get-in ~message [~k])))])
572574
`[~(symbol b) (get-in ~message [~k])]]
575+
(= :options match-kind)
576+
[`{~k (:or ~@(:options match-value))}
577+
`[~(symbol b) (get-in ~message [~k])]]
573578
:else
574579
[`{~k ~match-value}
575580
`[~(symbol b) (get-in ~message [~k])]]))
576581

577582
:optional-key-with-default-binding
578583
(let [k (make-key (:key body))
579584
b (make-binding (:binding body))]
580-
[{} `[~(symbol b) (get-in ~message [~k] ~(:default-value body))]])
585+
[{} `[~(symbol b) (get-in ~message [~k] ~(:default-value body))]])
581586

582587
:path-matches-without-binding
583588
(let [path (mapv make-key (:path body))
584589
match (:match-value body)
585-
predicate? (= :compare-fn (first match))
586-
match-value (second match)
587-
path-map (assoc-in {} path match-value)]
590+
match-kind (first match)
591+
match-value (second match)]
588592
(cond
589-
predicate?
593+
(= :compare-fn match-kind)
590594
[`(~(fold-path path '_) :guard [(constantly (~(:fn match-value) (get-in ~message ~path)))])
591595
`[]]
596+
(= :options match-kind)
597+
[(assoc-in {} path `(:or ~@(:options match-value)))
598+
`[]]
592599
:else
593-
[`~path-map
600+
[`~(assoc-in {} path match-value)
594601
`[]]))
595602

596603
:path-matches-with-binding
597604
(let [path (mapv make-key (:path body))
598605
b (make-binding (:binding body))
599606
match (:match-value body)
600-
predicate? (= :compare-fn (first match))
607+
match-kind (first match)
601608
match-value (second match)
602609
path-map (assoc-in {} path match-value)]
603610
(cond
604-
predicate?
611+
(= :compare-fn match-kind)
605612
[`(~(fold-path path '_) :guard [(constantly (~(:fn match-value) (get-in ~message ~path)))])
606613
`[~(symbol b) (get-in ~message ~path)]]
614+
(= :options match-kind)
615+
[(assoc-in {} path `(:or ~@(:options match-value)))
616+
`[~(symbol b) (get-in ~message ~path)]]
607617
:else
608618
[`~path-map
609619
`[~(symbol b) (get-in ~message ~path)]]))
@@ -625,11 +635,11 @@
625635
(defn parse-emit-match-syntax
626636
[message [pattern rhs]]
627637
(let [[lhss rhss] (reduce (fn [[clauses bindings] c]
628-
(let [[clause binding] (parse-emit-syntax message c)]
629-
[(conj clauses clause)
630-
(conj bindings binding)]))
631-
[[] []]
632-
pattern)]
638+
(let [[clause binding] (parse-emit-syntax message c)]
639+
[(conj clauses clause)
640+
(conj bindings binding)]))
641+
[[] []]
642+
pattern)]
633643
[(apply deep-merge lhss)
634644
`(let ~(into [] (apply concat rhss))
635645
~rhs)]))

test/active/clojure/match_test.clj

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@
4444
(t/testing "with regex"
4545
(let [c (p/parse-clause (:k #"foo"))]
4646
(t/is (= :k (p/key-matches-without-binding-clause-key c)))
47-
(t/is (= "foo" (.pattern ^java.util.regex.Pattern (p/regex-matcher-regex (p/key-matches-without-binding-clause-matcher c)))))
48-
))
47+
(t/is (= "foo" (.pattern ^java.util.regex.Pattern (p/regex-matcher-regex (p/key-matches-without-binding-clause-matcher c)))))))
4948
(t/testing "with any other value"
5049
(t/is (= (p/make-key-matches-without-binding-clause :k (p/make-constant-matcher "foo"))
5150
(p/parse-clause (:k "foo"))))))
@@ -149,10 +148,10 @@
149148
(t/deftest path-matches-with-binding-clause->rhs-match-test
150149
(t/is (= `[~(symbol "z") (get-in {:x {:y {:z "b"}}} [:x :y :z] "b")]
151150
(p/path-matches-with-binding-clause->rhs-match {:x {:y {:z "b"}}}
152-
(p/path-matches-with-binding-clause [:x :y :z] (p/match-const "b") "z"))))
151+
(p/path-matches-with-binding-clause [:x :y :z] (p/match-const "b") "z"))))
153152
(t/is (= `[~(symbol "rebind") (get-in {:x {:y {:z "b"}}} [:x :y :z] "b")]
154153
(p/path-matches-with-binding-clause->rhs-match {:x {:y {:z "b"}}}
155-
(p/path-matches-with-binding-clause [:x :y :z] (p/match-const "b") "rebind")))))
154+
(p/path-matches-with-binding-clause [:x :y :z] (p/match-const "b") "rebind")))))
156155

157156
(t/deftest reduce-lhs-test
158157
(t/is (empty? (p/reduce-lhs [])))
@@ -172,7 +171,6 @@
172171
{:a 42}
173172
(list {:z '_} :guard [:guard-3])]))))
174173

175-
176174
;; Testing Macro
177175

178176
(def one-data
@@ -235,9 +233,9 @@
235233
(t/is (= false (example-matcher three-data)))))
236234
(t/testing "Paths"
237235
(t/is (= [{}] ((p/map-matcher [([:a] :as a)] [a]) {:a {}})))
238-
(t/is (= [] ((p/map-matcher [([:a b] "c")] []) {:a { "b" "c"}})))
239-
(t/is (= [] ((p/map-matcher [([:a b c] "d")] []) {:a { "b" {"c" "d"}}})))
240-
(t/is (= ["d"] ((p/map-matcher [([:a b c] "d" :as z)] [z]) {:a { "b" {"c" "d"}}})))))
236+
(t/is (= [] ((p/map-matcher [([:a b] "c")] []) {:a {"b" "c"}})))
237+
(t/is (= [] ((p/map-matcher [([:a b c] "d")] []) {:a {"b" {"c" "d"}}})))
238+
(t/is (= ["d"] ((p/map-matcher [([:a b c] "d" :as z)] [z]) {:a {"b" {"c" "d"}}})))))
241239

242240
(t/deftest map-matcher-optional-test
243241
(t/testing "Optional values"
@@ -282,8 +280,7 @@
282280
(t/is (= ["D"] ((p/map-matcher [(? [:a b c] "D" :as a)] [a]) {:a "b"})))
283281
(t/is (= ["D"] ((p/map-matcher [(? [:a b c] "D" :as a)] [a]) {:a {"b" {}}})))
284282
(t/is (= ["D"] ((p/map-matcher [(? [:a b c] "D" :as a)] [a]) {:a {"b" {"e" "d"}}})))
285-
(t/is (= ["d"] ((p/map-matcher [(? [:a b c] "D" :as a)] [a]) {:a {"b" {"c" "d"}}})))
286-
))
283+
(t/is (= ["d"] ((p/map-matcher [(? [:a b c] "D" :as a)] [a]) {:a {"b" {"c" "d"}}})))))
287284

288285
(p/defpattern one-or
289286
[(:kind #"one")
@@ -306,6 +303,44 @@
306303
(example-or-matcher two-data)))
307304
(t/is (= false (example-or-matcher {:kind "none"})))))
308305

306+
(def example-or-matcher-inline
307+
(p/map-matcher
308+
[(:kind #"one")
309+
(:x (:or "a" "b" "c" "x") :as x)
310+
(:y (:or "x" "y" "z"))
311+
(:z :as z)
312+
:w]
313+
[x z]
314+
two [a c Z Y]
315+
:else false))
316+
317+
(t/deftest map-matcher-or-inline-test
318+
(t/testing "Alternative values to match on"
319+
(t/is (= ["x" "z"]
320+
(example-or-matcher-inline one-data)))
321+
(t/is (= ["a" "c" 42 23]
322+
(example-or-matcher-inline two-data)))
323+
(t/is (= false (example-or-matcher {:kind "none"})))))
324+
325+
(def example-or-matcher-inline-path
326+
(p/map-matcher
327+
[([:path :kind] #"one")
328+
([:path :x] (:or "a" "b" "c" "x") :as x)
329+
([:path :y] (:or "x" "y" "z"))
330+
([:path :z] :as z)
331+
[:path :w]]
332+
[x z]
333+
two [a c Z Y]
334+
:else false))
335+
336+
(t/deftest map-matcher-or-inline-path-test
337+
(t/testing "Alternative values to match on"
338+
(t/is (= ["x" "z"]
339+
(example-or-matcher-inline-path {:path one-data})))
340+
(t/is (= ["a" "c" 42 23]
341+
(example-or-matcher-inline-path two-data)))
342+
(t/is (= false (example-or-matcher {:kind "none"})))))
343+
309344
(p/defpattern predicate-pattern
310345
[(:x (:compare-fn even?))])
311346

@@ -379,13 +414,13 @@
379414
((p/map-matcher p x)
380415
evt)))))
381416
#_(t/testing "as constant with local parse-pattern"
382-
(let [x "x"
383-
evt {"X" x}
384-
p (p/parse-pattern [(X x)])]
385-
(t/is (= x
417+
(let [x "x"
418+
evt {"X" x}
419+
p (p/parse-pattern [(X x)])]
420+
(t/is (= x
386421
;; Caused by java.lang.UnsupportedOperationException Can't eval locals
387-
((p/map-matcher p x)
388-
evt))))))
422+
((p/map-matcher p x)
423+
evt))))))
389424

390425
(def doc-string-example-map-matcher
391426
(p/map-matcher
@@ -394,14 +429,14 @@
394429
(:z :as z)
395430
:w]
396431
(println x z)
397-
[(:a "a" :as a)
398-
(:b "b")
399-
(:c :as c)
400-
([:d] :as d)
401-
([:d Z] 42 :as Z)
402-
([:d Y] :as Y)
403-
([:d X] 65)
404-
[:d W foo]]
432+
[(:a "a" :as a)
433+
(:b "b")
434+
(:c :as c)
435+
([:d] :as d)
436+
([:d Z] 42 :as Z)
437+
([:d Y] :as Y)
438+
([:d X] 65)
439+
[:d W foo]]
405440
(println a c d Z Y)
406441
:else false))
407442

0 commit comments

Comments
 (0)