metosin / malli

High-performance data-driven data specification library for Clojure/Script.
Eclipse Public License 2.0
1.44k stars 204 forks source link

:and should short-circuit explanation - in some cases #1001

Open ikitommi opened 5 months ago

ikitommi commented 5 months ago

pulled from #993

Tangential

Depending on the validation it doesn't make sense to display all error messages. Consider:

(-> [:and
     [:vector :any]
     [:fn {:error/message "should be distinct"} #(= % (distinct %))]]
    (m/explain :invalid)
    (me/humanize))
; => ["invalid type" "should be distinct"]

But in other cases it might, such as a password field:

I don't have a suggestion and I'd need some hammock time pondering about this problem.

frenchy64 commented 3 months ago

I don't think this is a solvable problem if we require :and to be involved.

If instead we have a :distinct property, we can then have the explainer short circuit if the schema pred fails. Some schemas do this, but not -simple-schema.

If we make the necessary changes to -simple-schema's explainer we can get this behavior:

    (is (= ["invalid type"]
           (me/humanize (m/explain [:string {:distinct true}] nil))))
    (is (= ["should be distinct: \\[ provided 2 times"]
           (me/humanize (m/explain [:string {:distinct true}] "[["))))

To be an equivalent solution to :and + :fn it needs to be extensible (i.e., anyone can implement a property for any schema), which I have some ideas here: https://github.com/metosin/malli/pull/1025