Skip to content

Instantly share code, notes, and snippets.

@triss
Last active Nov 25, 2016
Embed
What would you like to do?
Getting ranges from specs...
;; Specs for matching
(defn- fn-wrapped-spec
[spec]
(s/spec (s/cat :fn #{'clojure.core/fn}
:args #{['%]}
:form (s/spec spec))))
(s/def ::int-in-range?-form
(s/cat :fn #{'clojure.spec/int-in-range?}
:min number?
:max number?
:x #{'%}))
(s/def ::int-in-form
(s/cat :and #{'clojure.spec/and}
:int? #{'clojure.core/int?}
:fn (fn-wrapped-spec ::int-in-range?-form)))
(s/def ::double-in-form
(s/cat :and #{'clojure.spec/and}
:double? #{'clojure.core/double?}
:max (fn-wrapped-spec (s/cat :<= #{'clojure.core/<=}
:x #{'%}
:max number?))
:min (fn-wrapped-spec (s/cat :<= #{'clojure.core/<=}
:min number?
:x #{'%}))))
(s/def ::range-spec-form
(s/or :double-in ::double-in-form
:int-in ::int-in-form))
;; Fns for extractining min/maximum
(defn double-in->min-max
[c] {:min (get-in c [:min :form :min])
:max (get-in c [:max :form :max])})
(defn int-in->min-max
[c] {:min (get-in c [:fn :form :min])
:max (get-in c [:fn :form :max])})
(defn form->min-max
[form]
(let [[t c] (s/conform ::range-spec-form form)]
(condp = t
:int-in (int-in->min-max c)
:double-in (double-in->min-max c))))
(def spec->min-max
(comp form->range s/form))
(comment
(s/def ::int-range (s/int-in 0 100))
(s/def ::double-range (s/double-in :min 0 :max 5.1))
(spec->min-max ::int-range)
(spec->min-max ::double-range))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment