Skip to content

Instantly share code, notes, and snippets.

@thosmos
Created October 21, 2016 07:24
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 thosmos/41c0b38bea3270988a3275332686ab49 to your computer and use it in GitHub Desktop.
Save thosmos/41c0b38bea3270988a3275332686ab49 to your computer and use it in GitHub Desktop.
js->clj using transients
(ns cljs_perf.core
(:require [goog.object :as gobject]))
(let [data
"[{ \"web-app\": { \"servlet\": [ { \"servlet-name\": \"cofaxCDS\", \"servlet-class\": \"org.cofax.cds.CDSServlet\", \"init-param\": { \"configGlossary:installationAt\": \"Philadelphia, PA\", \"configGlossary:adminEmail\": \"ksm@pobox.com\", \"configGlossary:poweredBy\": \"Cofax\", \"configGlossary:poweredByIcon\": \"/images/cofax.gif\", \"configGlossary:staticPath\": \"/content/static\", \"templateProcessorClass\": \"org.cofax.WysiwygTemplate\", \"templateLoaderClass\": \"org.cofax.FilesTemplateLoader\", \"templatePath\": \"templates\" } }, { \"servlet-name\": \"cofaxAdmin\", \"servlet-class\": \"org.cofax.cds.AdminServlet\" }, { \"servlet-name\": \"cofaxTools\", \"servlet-class\": \"org.cofax.cms.CofaxToolsServlet\", \"init-param\": { \"templatePath\": \"toolstemplates/\", \"log\": 1, \"logLocation\": \"/usr/local/tomcat/logs/CofaxTools.log\", \"logMaxSize\": \"\", \"dataLog\": 1, \"dataLogLocation\": \"/usr/local/tomcat/logs/dataLog.log\", \"dataLogMaxSize\": \"\", \"removePageCache\": \"/content/admin/remove?cache=pages&id=\", \"removeTemplateCache\": \"/content/admin/remove?cache=templates&id=\", \"fileTransferFolder\": \"/usr/local/tomcat/webapps/content/fileTransferFolder\", \"lookInContext\": 1, \"adminGroupID\": 4, \"betaServer\": true } } ], \"servlet-mapping\": { \"cofaxCDS\": \"/\", \"cofaxEmail\": \"/cofaxutil/aemail/*\", \"cofaxAdmin\": \"/admin/*\", \"fileServlet\": \"/static/*\", \"cofaxTools\": \"/tools/*\" }, \"taglib\": { \"taglib-uri\": \"cofax.tld\", \"taglib-location\": \"/WEB-INF/tlds/cofax.tld\" } } },
{\"menu\": { \"id\": \"file\", \"value\": \"File\", \"popup\": { \"menuitem\": [ {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"}, {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"}, {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"} ] } }} ]"
]
(def js-data (js/JSON.parse data)))
(defn js_to_clj_1
"Recursively transforms JavaScript arrays into ClojureScript
vectors, and JavaScript objects into ClojureScript maps. With
option ':keywordize-keys true' will convert object fields from
strings to keywords."
([x] (js->clj x :keywordize-keys false))
([x & opts]
(let [{:keys [keywordize-keys]} opts
keyfn (if keywordize-keys keyword str)
f (fn thisfn [x]
(cond
(satisfies? IEncodeClojure x)
(-js->clj x (apply array-map opts))
(seq? x)
(doall (map thisfn x))
(coll? x)
(into (empty x) (map thisfn x))
(array? x)
(vec (map thisfn x))
(identical? (type x) js/Object)
(into {} (for [k (js-keys x)]
[(keyfn k) (thisfn (aget x k))]))
:else x))]
(f x))))
(defn js_to_clj_2
"Recursively transforms JavaScript arrays into ClojureScript
vectors, and JavaScript objects into ClojureScript maps. With
option ':keywordize-keys true' will convert object fields from
strings to keywords."
([x] (js->clj x :keywordize-keys false))
([x & opts]
(let [{:keys [keywordize-keys]} opts
keyfn (if keywordize-keys keyword str)
f (fn thisfn [x]
(cond
(satisfies? IEncodeClojure x)
(-js->clj x (apply array-map opts))
(seq? x)
(doall (map thisfn x))
(coll? x)
(into (empty x) (map thisfn) x)
(array? x)
;(vec (map thisfn x))
(persistent!
(reduce #(conj! %1 (thisfn %2))
(transient []) x))
(identical? (type x) js/Object)
;(into {} (for [k (js-keys x)]
; [(keyfn k) (thisfn (aget x k))]))
(persistent!
(reduce (fn [r k] (assoc! r (keyfn k) (thisfn (gobject/get x k))))
(transient {}) (js-keys x)))
:else x))]
(f x))))
(defn ^:export js_to_clj []
(js_to_clj_1 js-data))
(defn ^:export js_to_clj_new []
(js_to_clj_2 js-data))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment