Created
March 16, 2013 00:30
-
-
Save lynaghk/5174289 to your computer and use it in GitHub Desktop.
Hacky "tagged literals" in JSON.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;5-minute sketch of tagged literals in JSON via the little known second argument to the browser's JSON.parse. | |
;;It's no EDN, but it's still a hell of a lot nicer than the usual JSON-deserialization state of affairs. | |
(ns shim.json | |
(:require [goog.date.DateTime :as DateTime])) | |
(defn parse-tagged-string | |
"Parse a tagged string within JSON. | |
Assumes string begins with a throwaway first character and there is a single space between the tag and its data." | |
[tagged-string] | |
(let [split-idx (.indexOf tagged-string " ") | |
tag (.substring tagged-string 1 split-idx) | |
d (.substring tagged-string (inc split-idx)) | |
handler (case tag | |
;;prefer plain JavaScript dates over goog.DateTimes. | |
"inst" #(js/Date. (DateTime/fromRfc822String %)))] | |
(handler d))) | |
(defn generate-tagged-string | |
"Replaces certain JavaScript objects with tagged string representations." | |
[key x] | |
(cond | |
(instance? goog.date.DateTime x) | |
(str "#inst " (.toXmlDateTime x true)) | |
:else x)) | |
(defn parse-json | |
"Parse JSON string using native handler with 'reviver' function that hooks into parse-tagged-string. | |
See: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse" | |
[json-str] | |
(.parse js/JSON json-str | |
(fn [k v] | |
(if (and (string? v) (= "#" (aget v 0))) | |
(parse-tagged-string v) | |
v)))) | |
(defn generate-json | |
"Generate a JSON string using native handler with a 'replacer' that uses tagged string representations." | |
[obj] | |
(.stringify js/JSON obj generate-tagged-string)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment