Skip to content

Instantly share code, notes, and snippets.

@favila
Last active December 29, 2015 01:29
Show Gist options
  • Save favila/7592950 to your computer and use it in GitHub Desktop.
Save favila/7592950 to your computer and use it in GitHub Desktop.
Macro to define a google closure compiler enum from clojurescript.
(ns defenum
(:require [clojure.string :as str]
cljs.compiler))
(defn unzip
([s] (unzip 2 s))
([n s] (apply map vector (partition n s))))
(defmacro jso
"Like js-obj, except the keys are emitted as unquoted munged symbols. Keys
must be literals (symbol, string, or keyword). Examples:
(js-obj \"a->b\" 1) => {\"a->b\":1}
; Before cljs r2060:
(js-obj 'a->b 1) => {new cljs.core.Symbol(null,\"a->b\",\"a->b\",-9,null):1}
; After cljs r2060: ERROR
(jso 'a->b 1) => {a__GT_b:1}"
([] `(cljs.core/js-obj))
([& fields]
{:pre [(every? (some-fn symbol? string? keyword?)
(apply concat fields (partition 1 2 fields)))]}
(let [[properties values] (map* fields)
js-tmpl (str/join "," (map (comp #(str % ":~{}")
cljs.compiler/munge name) properties))]
`(~'js* ~(str "{" js-tmpl "}") ~@values))))
(defmacro defenum [ename & fields]
`(def ^const ~ename "@const\n@enum {*}\n@struct"
(jso ~@fields)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment