Skip to content

Commit

Permalink
Split validator namespace into internal and external.
Browse files Browse the repository at this point in the history
  • Loading branch information
David Frese committed Mar 20, 2024
1 parent 58e3fe1 commit 7a7de63
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 47 deletions.
2 changes: 1 addition & 1 deletion src/active/data/struct/internal/closed_struct_map.cljc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns ^:no-doc active.data.struct.internal.closed-struct-map
(:require [active.data.struct.internal.struct-type :as struct-type]
[active.data.struct.internal.closed-struct-data :as data]
[active.data.struct.validator :as v]
[active.data.struct.internal.validator :as v]
#?(:clj [clojure.pprint :as pp]
:cljs [cljs.pprint :as pp])
[clojure.set :as set])
Expand Down
2 changes: 1 addition & 1 deletion src/active/data/struct/internal/struct_type.cljc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(ns ^:no-doc active.data.struct.internal.struct-type
(:require [active.data.struct.validator :as validator])
(:require [active.data.struct.internal.validator :as validator])
(:refer-clojure :exclude [alter-meta!
get-validator set-validator!
#?@(:cljs [contains? keys])]
Expand Down
39 changes: 39 additions & 0 deletions src/active/data/struct/internal/validator.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
(ns active.data.struct.internal.validator)

(defprotocol IMapValidator
"Note: Both methods are called on every construction and change;
usually only one of them needs to be implemented, resp. the other as
`(constantly nil)`."

(-validate-field! [this changed-key new-value]
"Throws an exception if the new value is not acceptable for the given key.")
(-validate-map! [this m]
"Throws an exception if an invariant is broken in the given map."
;; Note: m can be any kind of map; not guaranteed to be a
;; struct-map.
))

(defprotocol IDeferredMapValidator
(-get-validator! [this] "Return the the actual IMapValidator, or nil. Called once for each create/update of a map."))

(defn resolve! [t]
(if (satisfies? IDeferredMapValidator t)
(-get-validator! t)
t))

(defn validate-single! [t key value]
(-validate-field! t key value))

(defn validate-map-only! [t m]
(-validate-map! t m))

(defn validate!
([t m]
(assert (map? m))
(validate! t m (keys m) (vals m)))
([t m changed-keys changed-values]
(dorun (map (partial -validate-field! t)
changed-keys
changed-values))
(-validate-map! t m)))

52 changes: 8 additions & 44 deletions src/active/data/struct/validator.cljc
Original file line number Diff line number Diff line change
@@ -1,47 +1,11 @@
(ns active.data.struct.validator)

(defprotocol IMapValidator
"Note: Both methods are called on every construction and change;
usually only one of them needs to be implemented, resp. the other as
`(constantly nil)`."

(-validate-field! [this changed-key new-value]
"Throws an exception if the new value is not acceptable for the given key.")
(-validate-map! [this m]
"Throws an exception if an invariant is broken in the given map."
;; Note: m can be any kind of map; not guaranteed to be a
;; struct-map.
))

(defprotocol IDeferredMapValidator
(-get-validator! [this] "Return the the actual IMapValidator, or nil. Called once for each create/update of a map."))

(defn resolve! [t]
(if (satisfies? IDeferredMapValidator t)
(-get-validator! t)
t))

(defn validate-single! [t key value]
(-validate-field! t key value))

(defn validate-map-only! [t m]
(-validate-map! t m))

(defn validate!
([t m]
(assert (map? m))
(validate! t m (keys m) (vals m)))
([t m changed-keys changed-values]
(dorun (map (partial -validate-field! t)
changed-keys
changed-values))
(-validate-map! t m)))
(ns active.data.struct.validator
(:require [active.data.struct.internal.validator :as internal]))

(defn field-validators
"Returns a map validator that checks some of the fields individually."
[keys-fns-map]
(let [lookup keys-fns-map]
(reify IMapValidator
(reify internal/IMapValidator
(-validate-map! [this m] nil)
(-validate-field! [this changed-key new-value]
(when-let [f (lookup changed-key)]
Expand All @@ -59,15 +23,15 @@
(defn conditionally
"Returns a validator that passes validation on to the given validator, if `(condition)` is true, and does nothing otherwise."
[validator condition]
(if (satisfies? IDeferredMapValidator validator)
(if (satisfies? internal/IDeferredMapValidator validator)
;; resolve deferred->deferred
(reify IDeferredMapValidator
(reify internal/IDeferredMapValidator
(-get-validator! [this]
(when (condition)
(-get-validator! validator))))
(internal/-get-validator! validator))))
(do
(assert (satisfies? IMapValidator validator) validator)
(reify IDeferredMapValidator
(assert (satisfies? internal/IMapValidator validator) validator)
(reify internal/IDeferredMapValidator
(-get-validator! [this]
(when (condition)
validator))))))
1 change: 0 additions & 1 deletion test/active/data/struct_test.cljc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
(ns active.data.struct-test
(:require [active.data.struct :as sut #?@(:cljs [:include-macros true])]
#_[active.data.struct.validator :as validator]
#_[active.clojure.lens :as lens]
[clojure.data :as data]
#?(:clj [clojure.test :as t]
Expand Down

0 comments on commit 7a7de63

Please sign in to comment.