:key-fn function does not run on all keys
Hi, I am trying to jsonize some structure that has seqs as keys in a hashmap. I know json only likes strings for keys, so I'd like to control how the seq is being turned to a string.
Here is a simple example:
(json/generate-string
{[1 2] 1, :a 5}
{:key-fn (fn [k]
(println "key" k)
(str k))})
In here, only "key :a" is printed to screen and [1,2] implicitly turns into a string without running through the function.
Hmm.. perhaps this should be renamed to something like "keyword-fn" or else it should run on all of them. I'll look.
This has been open for a long time, but I ran into the same problem today. The documentation is a little vague in that :key-fn could be interpreted as a function to call on keys of maps, but it's actually a function called only on keys that are keywords in maps.
In my case, I am trying to hook the encoding of regexes in a map containing either string or regex keys, and was trying to use the key-fn for that.
(cheshire.core/generate-string foo {:key-fn (fn [v] (if (instance? java.util.regex.Pattern v) (str "/" v "/") v)})
and then:
(cheshire.core/parse-string foo {:key-fn (fn [v] (if (re-matches #"/.+/" v) (re-pattern (subs v 1 (dec (count v))) v)})
Doesn't work, because the key-fn is only called on keywords. Neither does adding a custom encoding, because custom encodings are only used for values, and are not applied to keys of maps.
The above is a simplification. I'm trying to avoid copying a huge map, and am actually using some low-level linkages with parse and generate with a generator/parser from the smile factory and direct i/o to/from streams.