A JSON encoder/parser for clojure
Switch branches/tags
Nothing to show
Pull request Compare This branch is 38 commits ahead, 1 commit behind dbishop:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



clojure-json is on clojars! http://clojars.org/org.danlarkin/clojure-json

To install from source you can lein install but likely you can just add this project as a dependency like it says on http://clojars.org/org.danlarkin/clojure-json.

Using The Encoder

user=> (require '(org.danlarkin [json :as json]))
user=> (print (json/encode [1 2 3 4 5]))
user=> (print (json/encode {:a 1 :b 2 :c 3}))
user=> (print (json/encode [1 2 3 4 5] :indent 2))
user=> (import '(java.io FileWriter))
user=> (json/encode-to-writer [1 2 3 4 5] (FileWriter. "/tmp/foo.json"))
#<FileWriter java.io.FileWriter@c93f91>
user=> (import '(java.util Date))
user=> (json/encode (Date.))
java.lang.Exception: Unknown Datastructure: Sat Nov 5 19:00:00 GMT 1605 (NO_SOURCE_FILE:0)
user=> (defn date-encoder
        [date writer pad current-indent start-token-indent indent-size]
        (.append writer (str start-token-indent \" date \")))
user=> (json/add-encoder java.util.Date date-encoder)
#<MultiFn clojure.lang.MultiFn@da6c0d>
user=> (print (json/encode (Date.)))
"Sat Nov 5 19:00:00 GMT 1605"nil
user=> (print (json/encode [(Date.) (Date.) (Date.)] :indent 2))
  "Sat Nov 5 19:00:00 GMT 1605",
  "Sat Nov 5 19:00:00 GMT 1605",
  "Sat Nov 5 19:00:00 GMT 1605"
user=> (print (json/encode {:foo (Date.) :bam 4 :quux 'bar} :indent 2))
  "foo":"Sat Nov 5 19:00:00 GMT 1605",

Obviously not all Clojure data structures have clear parallels in JSON. In particular, keywords become strings upon encoding, and strings used as keys become keywords upon decoding. For sets, you may bind org.danlarkin.encoder/*sets-as-maps* to true in order to get them encoded as maps of keys to themselves. This preserves O(1) lookup and callability of sets at the expense of calling seq on them.

Custom Encoding

clojure-json uses a multimethod for custom encoding, dispatching on type. If you're adding an encoder function for a container type make sure to respect all of the indentation arguments that your function will be passed and to call encode-helper on each of the elements in your container. I've left the parameters to date-encoder un-hinted in this example in the interest of brevity but their inclusion does seem to speed up execution time a good bit so I suggest using them where speed matters.

Using The Parser

user=> (require '(org.danlarkin [json :as json]))
user=> (json/decode "[1, 2, 3, 4, 5]")
[1 2 3 4 5]
user=> (json/decode "{\"foo\":1, \"bar\":2, \"baz\":3}")
{:foo 1, :bar 2, :baz 3}
user=> (json/decode "{\"foo\":[1,2,\"superbam\"], \"bar\":{\"bam\":98.6}, \"baz\":3}")
{:foo [1 2 "superbam"], :bar {:bam 98.6}, :baz 3}
user=> (json/decode-from-reader (FileReader. "/tmp/foo.json"))
[1 2 3 4 5]

Special Thanks

Special thanks go to Darrell Bishop of arubanetworks.com for writing the parser included in this distribution.