Skip to content

Instantly share code, notes, and snippets.

@lynaghk
Created March 16, 2013 00:30
Show Gist options
  • Save lynaghk/5174289 to your computer and use it in GitHub Desktop.
Save lynaghk/5174289 to your computer and use it in GitHub Desktop.
Hacky "tagged literals" in JSON.
;;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