plumatic / schema

Clojure(Script) library for declarative data description and validation
Other
2.41k stars 257 forks source link

Using `conditional` with primitives #318

Closed mbossenbroek closed 8 years ago

mbossenbroek commented 8 years ago

Just started playing with the new conditional operator and I'm wondering if I'm using it right.

When using either, the validation messages leave much to be desired:

=> (s/check (s/either s/Str s/Keyword) 42)
(not (some-matching-either-clause? 42))

The docstring says as much, and to use conditional instead, but this is the result I came up with:

=> (s/check (s/conditional
              string? s/Str
              keyword? s/Keyword
              'string-or-keyword) 42)
(not (string-or-keyword 42))

The problem with this one is that the conditions are actually doing the validation in these cases. Does it make sense to validate that something is a string after checking that it's a string? It's also a bit verbose for something so simple.

Is there a more succinct way to express combinations of primitive types, or is that the recommended way?

w01fe commented 8 years ago

For this case you can use (s/cond-pre s/Str s/Keyword) -- it works like either, but is only suitable for superficially different types as in this case. The advantage is that unlike either, it never backtracks (which has significant advantages from an implementation point of view). However, if you want a nicer error message, what you have is about as good as it gets.

mbossenbroek commented 8 years ago

Makes sense. Thanks!