Skip to content

Commit

Permalink
Add key-fn and value-fn to parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Stuart Sierra committed Sep 14, 2012
1 parent 94e71e1 commit 8487376
Showing 1 changed file with 39 additions and 16 deletions.
55 changes: 39 additions & 16 deletions src/main/clojure/clojure/data/json_new.clj
Expand Up @@ -16,8 +16,9 @@


;;; JSON READER ;;; JSON READER


(def ^:dynamic ^:private *keywordize*)
(def ^:dynamic ^:private *bigdec*) (def ^:dynamic ^:private *bigdec*)
(def ^:dynamic ^:private *key-fn*)
(def ^:dynamic ^:private *value-fn*)


(declare -parse) (declare -parse)


Expand Down Expand Up @@ -81,8 +82,11 @@
(recur element result) (recur element result)
(throw (Exception. "JSON error (non-string key in object)"))) (throw (Exception. "JSON error (non-string key in object)")))
(recur nil (recur nil
(assoc! result (if *keywordize* (keyword key) key) (let [out-key (*key-fn* key)
element))))))))) out-value (*value-fn* out-key element)]
(if (= *value-fn* out-value)
result
(assoc! result out-key out-value)))))))))))


(defn- parse-hex-char [^PushbackReader stream] (defn- parse-hex-char [^PushbackReader stream]
;; Expects to be called with the head of the stream AFTER the ;; Expects to be called with the head of the stream AFTER the
Expand Down Expand Up @@ -209,11 +213,6 @@
"Parse a single item of JSON data from a java.io.Reader. Options are "Parse a single item of JSON data from a java.io.Reader. Options are
key-value pairs, valid options are: key-value pairs, valid options are:
:keywordize boolean
If true (default) convert JSON property names from strings
into keywords.
:bigdec boolean :bigdec boolean
If true use BigDecimal for decimal numbers instead of Double. If true use BigDecimal for decimal numbers instead of Double.
Expand All @@ -226,15 +225,39 @@
:eof-value Object :eof-value Object
Object to return if the stream is empty and eof-error? is Object to return if the stream is empty and eof-error? is
false. Default is nil." false. Default is nil.
:key-fn function
Single-argument function called on JSON property names; return
value will replace the property names in the output. Default
is clojure.core/keyword.
:value-fn function
Function to transform values in the output. For each JSON
property, value-fn is called with two arguments: the property
name (transformed by key-fn) and the value. The return value
of value-fn will replace the value in the output. If value-fn
returns itself, the property will be omitted from the output.
Finally, value-fn is called with one argument, the whole
object, and may return any any substitute value.
The default value-fn is (fn ([v] v) ([k v] v))."
[reader & options] [reader & options]
(let [{:keys [keywordize eof-error? eof-value bigdec] (let [{:keys [eof-error? eof-value bigdec key-fn value-fn]
:or {keywordize false :or {bigdec false
bigdec false eof-error? true
eof-error? true}} options] key-fn keyword
(binding [*keywordize* keywordize value-fn (fn ([v] v) ([k v] v))}} options]
*bigdec* bigdec] (binding [*bigdec* bigdec
(-parse reader eof-error? eof-value)))) *key-fn* key-fn
*value-fn* value-fn]
(let [out-value
(*value-fn* (-parse reader eof-error? eof-value))]
(when-not (= *value-fn* out-value)
out-value)))))


(defn parse-string (defn parse-string
"Reads one JSON value from input String. Options are the same as for "Reads one JSON value from input String. Options are the same as for
Expand Down

0 comments on commit 8487376

Please sign in to comment.