Last active
October 26, 2017 11:00
-
-
Save danielneal/43c8dc5d0d3a1d4cadd55d965f5076c1 to your computer and use it in GitHub Desktop.
How to get the args of a fn spec?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; How do I get the args of a fn spec? | |
;; (I'd like to do some kind of dumb intellisense using specs in the registry) | |
;; For example, with a function a | |
(defn a [m] | |
(get m :foo)) | |
(s/fdef a | |
:args (s/cat :m map?) | |
:ret int?) | |
;; Get it's spec out of the registry | |
(def a-spec | |
(get (s/registry) (symbol (str *ns*) "a"))) | |
;; parse the spec | |
(s/def | |
::fn-spec | |
(s/cat :fspec- #{'clojure.spec.alpha/fspec} | |
:args- #{:args} | |
:args (s/spec (s/cat :cat- #{'clojure.spec.alpha/cat} | |
:args (s/* (s/cat :arg keyword? :spec any?)))) | |
:ret- #{:ret} | |
:ret any? | |
:fn- #{:fn} | |
:fn any?)) | |
(get-in (s/conform ::fn-spec (s/form a-spec)) [:args :args]) | |
;; gives this | |
[{:arg :m, :spec clojure.core/map?}] | |
;; but that :spec is a quoted list - to turn it back into a spec, I could | |
;; possibly do eval | |
(def arg-spec (s/spec (eval (-> (s/conform ::fn-spec (s/form a-spec)) | |
:args | |
:args | |
first | |
:spec)))) | |
;; => #object[clojure.spec.alpha$spec_impl$reify__739 0x69ada674 "clojure.spec.alpha$spec_impl$reify__739@69ada674"] | |
(s/valid? arg-spec {:a 1}) ;=> true | |
;;; but maybe there is a better way? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment