-
Notifications
You must be signed in to change notification settings - Fork 21
/
parser.cljc
133 lines (112 loc) · 3.48 KB
/
parser.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
(ns matcher-combinators.parser
(:require [matcher-combinators.core :as core]
[matcher-combinators.matchers :as matchers])
#?(:clj
(:import [clojure.lang Keyword Symbol Ratio BigInt IPersistentMap
IPersistentVector IPersistentList IPersistentSet
LazySeq Repeat Cons Var]
[java.util UUID Date]
[java.util.regex Pattern]
[java.time LocalDate LocalDateTime LocalTime YearMonth])))
#?(:cljs
(extend-protocol
core/Matcher
;; function as predicate
function
(match [this actual]
(core/match-pred this actual))
;; equals base types
nil
(match [this actual]
(core/match (matchers/equals this) actual))
number
(match [this actual]
(core/match (matchers/equals this) actual))
string
(match [this actual]
(core/match (matchers/equals this) actual))
boolean
(match [this actual]
(core/match (matchers/equals this) actual))
Keyword
(match [this actual]
(core/match (matchers/equals this) actual))
UUID
(match [this actual]
(core/match (matchers/equals this) actual))
js/Date
(match [this actual]
(core/match (matchers/equals this) actual))
Var
(match [this actual]
(core/match (matchers/equals this) actual))
;; equals nested types
Cons
(match [this actual]
(core/match (matchers/equals this) actual))
Repeat
(match [this actual]
(core/match (matchers/equals this) actual))
default
(match [this actual]
(cond
(satisfies? IMap this)
(core/match (matchers/embeds this) actual)
(or (satisfies? ISet this)
(satisfies? ISequential this))
(core/match (matchers/equals this) actual)))
js/RegExp
(match [this actual]
(core/match (matchers/regex this) actual))))
#?(:clj (do
(defmacro mimic-matcher [matcher-builder & types]
`(extend-protocol
core/Matcher
~@(mapcat (fn [t] `(~t
(match [this# actual#]
(core/match (~matcher-builder this#) actual#)))) types)))
(defmacro mimic-matcher-java-primitives [matcher-builder & type-strings]
(let [type-pairs (->> type-strings
(map symbol)
(mapcat (fn [t] `(~t
(match [this# actual#]
(core/match (~matcher-builder this#) actual#))))))]
`(extend-protocol core/Matcher ~@type-pairs)))
(extend-type clojure.lang.Fn
core/Matcher
(match [this actual]
(core/match-pred this actual)))
(mimic-matcher-java-primitives matchers/equals
"[B")
(mimic-matcher matchers/equals
nil
java.lang.Class
Integer
Short
Long
Float
Double
String
Symbol
Keyword
Boolean
UUID
Date
LocalDate
LocalDateTime
LocalTime
YearMonth
Ratio
BigDecimal
BigInteger
BigInt
Character
Var)
(mimic-matcher matchers/embeds IPersistentMap)
(mimic-matcher matchers/equals IPersistentVector)
(mimic-matcher matchers/equals IPersistentList)
(mimic-matcher matchers/equals IPersistentSet)
(mimic-matcher matchers/equals Cons)
(mimic-matcher matchers/equals Repeat)
(mimic-matcher matchers/equals LazySeq)
(mimic-matcher matchers/regex Pattern)))