Reputation: 1416
According to Spec Guide
*
regular expression operator: checks 0 or more of a predicate/pattern, as this:
(s/def ::seq-of-keywords (s/* keyword?))
;; opts are alternating keywords and booleans
(s/def ::opts (s/* (s/cat :opt keyword? :val boolean?)))
(s/conform ::opts [:silent? false :verbose true])
;;=> [{:opt :silent?, :val false} {:opt :verbose, :val true}]
But as I understand it, s/cat
checks a sequence.
So why (s/* (s/cat))
is not for checking a sequence of sequence each of which conforms to (s/cat)
.
Something like this:
(s/conform ::opts [[:silent? false] [:verbose true]])
Why does it act like s/*
flatten
ed s/cat
? Or How can I check for something like [[:silent? false] [:verbose true]]
?
Upvotes: 2
Views: 560
Reputation: 13483
Why does ...
s/*
flattens/cat
?
... because a regular expression is a structured specification of a flat sequence. To paraphrase the Spec Guide to Sequences ...
s/spec
.How can I spec something like
[[:silent? false] [:verbose true]]
?
To spec a sequence of pairs, each of which is a keyword followed by a boolean:
(s/def ::opts (s/* (s/spec (s/cat :opt keyword? :val boolean?))))
Note the s/spec
wrapping the s/cat
. Now, for example, ...
=> (s/conform ::opts [[:silent? false] [:verbose true]])
[{:opt :silent?, :val false} {:opt :verbose, :val true}]
You can, of course, as akond does, use
s/tuple
instead of s/cat
ands/coll-of
instead of s/*
with no need for the interposed s/spec
.
Upvotes: 0
Reputation: 16060
You do that by using coll-of
:
(s/conform (s/coll-of ::opts) [[:silent? false] [:verbose true]])
=> [[{:opt :silent?, :val false}] [{:opt :verbose, :val true}]]
Sometimes it helps to generate sample data:
(gen/generate (s/gen ::opts))
=> (:aqfR6b*C/. false :?.03/Vu7? false :Y17UL0/McsI5h true)
which does not match the pattern of [[:silent? false] [:verbose true]]
But this one should be probably closer to what you are looking for:
(gen/generate (s/gen (s/coll-of (s/tuple keyword? boolean?))))
=> [[:X_o.u?7i/o.dIgTy false] [:L?*/_WY._:z true] [:X26:-j/l2q!u-7I false]]
Upvotes: 1