Skip to content

Instantly share code, notes, and snippets.

@aphyr
Created April 16, 2017 21:12
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aphyr/35e303223f8760e7f72109132dfd8a63 to your computer and use it in GitHub Desktop.
Save aphyr/35e303223f8760e7f72109132dfd8a63 to your computer and use it in GitHub Desktop.
Extract a schema from a clojure object
(require '[clojure.walk :as w])
(defmacro both [a b pred] `(and (~pred ~a) (~pred ~b)))
(defn union-structure [a b]
(cond (= a b) a
(both a b vector?) [(reduce union-structure (concat a b))]
(both a b map?) (merge-with union-structure a b)
; Dunno, said the ghoul
true (list 'U a b)))
(defn structure [x]
(cond (map? x)
(into {} (map (fn [[k v]] [k (structure v)]) x))
; Assume vectors are homogenous and collapse them
(vector? x) [(reduce union-structure (map structure x))]
true
(symbol (.getName (class x)))))
(structure {:people [{:name "kyle"
:pets [{:name "pup"
:type "samoyed"
:woof :bark}]}
{:name "kit"
:pets [{:name "woofs"
:type "husker"
:woof :arf
:extra? :very}]}]})
; returns
{:people [{:name java.lang.String
:pets [{:extra? clojure.lang.Keyword
:name java.lang.String
:type java.lang.String
:woof clojure.lang.Keyword}]}]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment