Search code examples
clojureedncheshire

How can I convert EDN output to JSON which has custom readers defined


In Clojure, I am using 'generate-string' function of cheshire (https://github.com/dakrone/cheshire) library to convert EDN to JSON.

It works fine for EDN without custom readers. For ex:

sample.edn: 
{:foo "bar" :baz {:eggplant [1 2 3]}

sample.clj:
(generate-string (edn/read-string (slurp sample.edn))


Output =>
{
  "foo": "bar",
  "baz": {
    "eggplant": [1,2,3]
  }
}

But if the EDN has custom readers which calls java code to create new object, then it fails to convert EDN output to JSON.

For ex:

EDN file:
{
   "version" "1.0"
   "xyz" #xyz/builder "testString"
}


Clojure code:

(defn getXyz [str]
    (.getXyz (XyzBuilder.) str)
)

(defn custom-readers []
    {'xyz/builder getXyz}
)

(edn/read-string
                {:readers (custom-readers)}
                (slurp filename)
)

If EDN file looks like above, it fails to generate JSON output since EDN output contains hashcode of the object created like

{"version" "1.0", 
 "Xyz" #object[com.java.sample.Xyz 0x6731787b "Xyz [type=type_1]"]}

Is there a way to generate JSON out of above output?

Thanks in advance.


Solution

  • Adding custom encoder like below helps to solve this.

    (add-encoder com.java.sample.Xyz
        (fn [c jsonGenerator]
            (.writeString jsonGenerator (str c))))