schema: combining constrained with other predicates

135 views
Skip to first unread message

Bruno Bonacci

unread,
May 25, 2016, 8:12:49 AM5/25/16
to Plumbing and Graph: the Clojure utility belt

Hi,

I'm extending schema to cover some common validations in my dataset,
and I'm trying to combine standard predicates with some custom one.

One example could be to validate that a value is a string and that isn't longer than a certain size.
My predicate look as follow:

 

(defn max-length

  [max-size]

  (s/pred (fn [s] (>= max-size (count s)))

          (str "max-length[" max-size "]")))

 

(s/validate (s/both s/Str (max-length 5)) "hello")

;;=> "hello"

 

(s/validate (s/both s/Str (max-length 5)) "hello!")

;;=> ExceptionInfo Value does not match schema: (not ("max-length[5]" "hello!"))

 

 

Now  both is deprecated in favour of constrained. However constrain doesn't accept predicated but just functions:

 

(s/validate (s/constrained s/Str (max-length 5)) "hello")

;;=> Not a function: schema.core.Predicate@b79b020b

 


If I turn the max-length predicate into a simple function it works but the errors messages are useless:

 

(defn max-length2

  [max-size]

  (fn [s] (>= max-size (count s))))

 

(s/validate (s/constrained s/Str (max-length2 5)) "hello!")

;;=> Value does not match schema: (not (user$max-length2/fn--23140 "hello!"))

 

 

Is there any reason why constrained doesn't accept predicates? 
Do you guys have any suggestion on how to improve this scenario?

Thanks
Bruno

Jason Wolfe

unread,
May 25, 2016, 8:21:43 AM5/25/16
to Bruno Bonacci, Plumbing and Graph: the Clojure utility belt
Hi Bruno,

Thanks for the detailed question. Constrained takes a third argument with predicate name. Or you can just give the predicate function a name.  Is that what you're looking for?

Best,
Jason

Bruno Bonacci

unread,
May 25, 2016, 8:30:58 AM5/25/16
to Jason Wolfe, Plumbing and Graph: the Clojure utility belt
Hi Jason,

thanks for the quick reply.

I've seen the predicate name in constrained but that one is for the whole predicate which it doesn't tell you much 
about which of the individual constrained failed. consider

 

  (s/constrained s/Int is-fib? is-square? is-prime? "complex constraint")

 

 

the error will be something like:

 

  ;;=> ExceptionInfo Value does not match schema: (not ("complex constraint" 76))

 

 

but you don't have any clue which of the predicate function failed.

Bruno

Jason Wolfe

unread,
May 26, 2016, 11:33:42 AM5/26/16
to Bruno Bonacci, Plumbing and Graph: the Clojure utility belt
s/constrained only takes a single predicate.  If you want multiple constraints, you can wrap multiple times.  
(s/constrained (s/constrained s/Int is-fib?) is-square?).

Best,
Jason
Reply all
Reply to author
Forward
0 new messages