Converting between vector (hiccup) and map-syntax:
(defn ->map-syntax
([?schema] (->map-syntax ?schema nil))
([?schema options] (m/accept ?schema m/map-syntax-visitor options)))
(defn <-map-syntax
([m] (<-map-syntax m nil))
([{:keys [name properties children]} options]
(let [<-child (if (-> children first vector?) (fn [f] #(update % 2 f)) identity)]
(m/into-schema name properties (mapv (<-child #(<-map-syntax % options)) children)))))
=>
(def Schema
[:map
[:id string?]
[:tags [:set keyword?]]
[:address
[:vector
[:map
[:street string?]
[:lonlat [:tuple double? double?]]]]]])
(->map-syntax Schema)
;{:name :map,
; :children [[:id nil {:name string?}]
; [:tags nil {:name :set
; :children [{:name keyword?}]}]
; [:address nil {:name :vector,
; :children [{:name :map,
; :children [[:street nil {:name string?}]
; [:lonlat nil {:name :tuple
; :children [{:name double?} {:name double?}]}]]}]}]]}
(-> Schema
(->map-syntax)
(<-map-syntax))
;[:map
; [:id string?]
; [:tags [:set keyword?]]
; [:address
; [:vector
; [:map
; [:street string?]
; [:lonlat [:tuple double? double?]]]]]]
Should the support for map-syntax be baked into malli.core
directly? One could create a schema with m/schema
using either one (can’t mix - the whole Schema tree needs to be created with same syntax - not to lose any extensibility) and the created Schema would know the syntax it’s created with: m/form
would return in the original one.
hmm. maybe not now (thinking aloud), have some really big map schemas in a project with a lot of properties everywhere, that could benefit from map-syntax, but should verify it first.
will just push the helpers into malli.
merged. Also, added a docs/tips.md
to collect stuff from here. All tips, docs welcome! https://github.com/metosin/malli/blob/master/docs/tips.md
Asciidoc might be a better format as it has the table of contents etc.