Skip to content

Instantly share code, notes, and snippets.

@brandonbloom
Created January 6, 2017 05:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brandonbloom/59d3e0d002f34b67f3ee2e99224745fa to your computer and use it in GitHub Desktop.
Save brandonbloom/59d3e0d002f34b67f3ee2e99224745fa to your computer and use it in GitHub Desktop.
(ns spec-context
(:require [clojure.spec :as s]))
(defmulti node-spec ::fancy?)
(defmethod node-spec true [_] ::fancy-node)
(defmethod node-spec :default [_] ::boring-node)
(s/def ::node (s/multi-spec node-spec ::fancy?))
(s/def ::fancy? boolean?)
(s/def ::children (s/every ::node))
(s/def ::boring-node (s/keys :req [::children]))
(s/def ::fancy-node (s/keys :req [::children ::flair]))
(s/def ::flair number?)
(defn make-fancy [node]
(-> node
(update ::children #(mapv make-fancy %))
(assoc ::fancy? true)))
(comment
(def boring {::children [{::children []}]})
(def fancy {::flair 1 ::children [{::flair 2 ::children []}]})
(def invalid {::flair 1 ::children [{::children []}]})
(make-fancy boring)
;; All fine.
(s/explain ::node boring)
(s/explain ::node fancy)
(s/explain ::node invalid)
(s/explain ::node (make-fancy fancy)) ; Good!
(s/explain ::node (make-fancy invalid)) ; No good, nested!
(s/explain ::node (make-fancy boring)) ; No good, two places!
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment