Skip to content

Instantly share code, notes, and snippets.

@jeroenvandijk
Last active August 22, 2018 15:45
Show Gist options
  • Save jeroenvandijk/4fb995a45e49d0e9986d2005ee5840d9 to your computer and use it in GitHub Desktop.
Save jeroenvandijk/4fb995a45e49d0e9986d2005ee5840d9 to your computer and use it in GitHub Desktop.
clojure.spec being strict on superfluous keys
;; If you want to fail before your old https://github.com/plumatic/schema
;; function fails the strict-keys macros below will help you find it.
(require '[clojure.spec.alpha :as s]
'[clojure.set])
(defn allowed-keys? [ks]
(fn [m]
(empty? (clojure.set/difference (set (keys m)) ks))))
;; Strict like schema ofs https://github.com/plumatic/schema
(defmacro strict-keys [& {:keys [req-un opt-un req opt] :as config}]
(let [allowed-keys (set (concat req opt (map (comp keyword name) (concat req-un opt-un))))]
`(s/and (s/keys ~@(mapcat seq config))
(allowed-keys? ~allowed-keys))))
(comment
(s/explain-data (strict-keys :req [:foo/bar]) {:foo/bar 1 :foo/baz 1})
;; => {:clojure.spec.alpha/problems [{:path [], :pred (user/allowed-keys? #{:foo/bar}), :val {:foo/bar 1, :foo/baz 1}, :via [], :in []}], :clojure.spec.alpha/spec #object[clojure.spec.alpha$and_spec_impl$reify__47870 0x79dcdd90 "clojure.spec.alpha$and_spec_impl$reify__47870@79dcdd90"], :clojure.spec.alpha/value {:foo/bar 1, :foo/baz 1}}
)
@jeroenvandijk
Copy link
Author

jeroenvandijk commented Aug 22, 2018

Probably better to use the strict-keys macro in Bruce Bauman's spell spec library defined over here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment