Reputation: 4132
I'm trying to do a validation for key value in a vector using plumatic-schema but the error message is not clear for me, here's what I'm trying to do:
;validating array with maps, it works
(s/validate [{}] [{} {}])
=> [{} {}]
;validating array with key and map (any lenght), not work
(s/validate [s/Int {}] [0 {} 1 {}])
[Int {}] is not a valid sequence schema;
a valid sequence schema consists of zero or more `one` elements, followed by zero or more
`optional` elements, followed by an optional schema that will match the remaining elements.
My question is, do you know what am I doing wrong? And the real meaning of this error?
The goal actually is to use this validation for a function call,
eg:
(s/defn example [items :- [(s/one s/Int "i") (s/one {} "v")]] ...)
;the call should be valid for cases like this
(example [0 {} 1 {} 2 {} 3 {}])
(example [0 {}])
Upvotes: 0
Views: 694
Reputation: 29984
See these docs:
Here is code showing how it works:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[schema.core :as s]))
(dotest
(is= [{} {}]
(spyx (s/validate
[{}]
[{} {}])))
(is= [0 {}]
(s/validate
[(s/one s/Int "int-1")
(s/one {} "map-2")]
[0 {}]))
(is= [0 {} 1 {}]
(s/validate
[(s/one s/Int "int-1")
(s/one {} "map-2")
(s/one s/Int "int-3")
(s/one {} "map-4")]
[0 {} 1 {}])) )
If you want to validate arbitrary lengths of alternating int & map, you may have to do a little prep work:
(defn validate-alternate-int-and-map
[some-seq]
(let [pairs (partition 2 some-seq)
all-int (mapv first pairs)
all-map (mapv second pairs)]
(assert (= (count all-map)
(count all-int)))
(s/validate [s/Int] all-int)
(s/validate [{}] all-map)
some-seq))
(dotest
(is= [0 {}] (validate-alternate-int-and-map [0 {}]))
(is= [0 {} 1 {}] (validate-alternate-int-and-map [0 {} 1 {}]))
(is= [0 {} 1 {} 2 {}] (validate-alternate-int-and-map [0 {} 1 {} 2 {}]))
)
P.S.
I also have some pre-defined schemas (e.g. KeyMap
, Pair
, etc) that I find very handy in the tupelo.schema namespace.
Upvotes: 1