Exclusive keys in a map schema
biiwide opened this issue · 2 comments
Is there currently a good or recommended way to define a schema for a map that fails when unspecified keys are present? In other words something like (conforms? '{:a int} {:a 2 :b "2"}) that evaluates as false instead of true.
I did spot the "disallowed-keys" test case which uses a schema like {(or :a :b) int}, but this seems like it would be unwieldy for maps with more than a couple entries or entries with differing schemata for their respective values.
In general, I'm not too worried about maps having extra keys so there's no short-hand for that situation. However, if a particular key would be bad, you can use something like '{:a int :bad? nil} to force :bad not to be there (actually, require the value to be nil but that's pretty close.)
But given your requirement for excluding unknown keys, let's say you want to allow only :a, :b, or :c as keys. You can use and
to require one item satisfies multiple constraints. My example below takes advantage of the two styles of map notation. The first with literal keys. The second one applies to all map entries (implicit +).
(h/conforms? '(and {:a int :b str} {(or :a :b :c) any}) {:a 1 :b "foo" :c 3})
;= true
(h/conforms? '(and {:a int :b str} {(or :a :b :c) any}) {:a 1 :b "foo" :d 10})
;= false because of :d
I hope that works for you.
That looks like it could work. I'll give it a try.
Thanks for the help.