Say I have the following Schema for some input I'm receiving from the outside world:
(def my-schema
{(s/optional-key :foo) Bool
(s/optional-key :baz) Bool
(s/optional-key :bar) Bool})
With the above, all or none of the keys can be present or missing in the map I'm validating, makes sense. However, what if I want to make sure that at least one of them is present?
I can certainly perform an additional separate check after Schema has validated the above and make sure that the key count >= 1, but I'm curious if there's a way of enforcing that in Schema definitions themselves.
Thoughts?
You can specify whatever predicate you want in your schemas:
(def my-schema
(s/both
(s/pred (complement empty) 'not-empty)
{(s/optional-key :foo) Bool
(s/optional-key :baz) Bool
(s/optional-key :bar) Bool}))
If you are asking how to validate the map using just the built-in predicates you could write:
(def my-schema
(s/both
{(s/optional-key :foo) Bool
(s/optional-key :baz) Bool
(s/optional-key :bar) Bool}
(s/either
{:foo Bool s/Any s/Any}
{:baz Bool s/Any s/Any}
{:bar Bool s/Any s/Any})))
which is pretty ugly and a lot more verbose than the pred
example
Another way to do this (probably better) is to use constrained:
(def my-schema
(s/constrained
{(s/optional-key :foo) Bool
(s/optional-key :baz) Bool
(s/optional-key :bar) Bool}
(fn [{:keys foo baz bar}]
(or foo bar bar))
"At least one of the keys is required")))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With