Search code examples
jsonclojure

clojure.data.json/write: application of predicate to determine value quoting


Suppose I have a simple map, example-map:

(def example-map {"a" "b" "c" "d"}) 

I can use clojure.data.json/write-str to JSON-ify this map as such:

(clojure.data.json/write-str example-map) =>
"{\"a\":\"b\",\"c\":\"d\"}"

I would like to apply a predicate to all keys to determine if that key is quoted, even if the output is invalid JSON.

The desired function would work as follows:

(defn to-quote? [v] (= v "d"))

(fictional-write-str example-map :quote-rule to-quote?) =>
"{\"a\":\"b\",\"c\":d}"

Might the optional :value-fn parameter to clojure.data.json/write-json offer what I'm describing?


Solution

  • write-str works via protocol JSONWriter, which you can extend with, say, clojure.lang.Symbol and have you own way.

    (ns reagenttest.main
        (:refer-clojure :exclude (read))
        (:require [clojure.data.json :as json]))
    
    (defn- write-named [x out]
        (.print out (name x)))
    
    (extend clojure.lang.Symbol json/JSONWriter {:-write write-named})
    
    (prn (json/write-str {"a" 'd "b" "c" "e" :key}))
    

    shows

    "{\"a\":d,\"b\":\"c\",\"e\":\"key\"}"