Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow parser customizations via protocol #203

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 35 additions & 18 deletions src/cheshire/core.clj
Original file line number Diff line number Diff line change
@@ -191,6 +191,9 @@
(.toByteArray baos))))

;; Parsers
(def ^{:dynamic true}
*parser* nil)

(defn parse-string
"Returns the Clojure object corresponding to the given JSON-encoded string.
An optional key-fn argument can be either true (to coerce keys to keywords),
@@ -206,10 +209,12 @@
([^String string key-fn array-coerce-fn]
(when string
(parse/parse
(or *parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader (StringReader. string))
key-fn nil array-coerce-fn))))
nil))))

;; Parsing strictly
(defn parse-string-strict
@@ -226,10 +231,12 @@
([^String string key-fn array-coerce-fn]
(when string
(parse/parse-strict
(or *parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader (StringReader. string))
key-fn nil array-coerce-fn))))
nil))))

(defn parse-stream
"Returns the Clojure object corresponding to the given reader, reader must
@@ -250,10 +257,12 @@
([^BufferedReader rdr key-fn array-coerce-fn]
(when rdr
(parse/parse
(or *parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader rdr)
key-fn nil array-coerce-fn))))
nil))))

(defn parse-stream-strict
"Returns the Clojure object corresponding to the given reader, reader must
@@ -270,10 +279,12 @@
([^BufferedReader rdr key-fn array-coerce-fn]
(when rdr
(parse/parse-strict
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader rdr)
key-fn nil array-coerce-fn))))
(or *parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader rdr)
nil))))

(defn parse-smile
"Returns the Clojure object corresponding to the given SMILE-encoded bytes.
@@ -287,9 +298,11 @@
([^bytes bytes key-fn array-coerce-fn]
(when bytes
(parse/parse
(or *parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
(.createParser ^SmileFactory (or factory/*smile-factory*
factory/smile-factory) bytes)
key-fn nil array-coerce-fn))))
nil))))

(defn parse-cbor
"Returns the Clojure object corresponding to the given CBOR-encoded bytes.
@@ -303,21 +316,23 @@
([^bytes bytes key-fn array-coerce-fn]
(when bytes
(parse/parse
(or *parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
(.createParser ^CBORFactory (or factory/*cbor-factory*
factory/cbor-factory) bytes)
key-fn nil array-coerce-fn))))
nil))))

(def ^{:doc "Object used to determine end of lazy parsing attempt."}
eof (Object.))

;; Lazy parsers
(defn- parsed-seq*
"Internal lazy-seq parser"
[^JsonParser parser key-fn array-coerce-fn]
[p ^JsonParser jp]
(lazy-seq
(let [elem (parse/parse-strict parser key-fn eof array-coerce-fn)]
(let [elem (parse/parse-strict p jp eof)]
(when-not (identical? elem eof)
(cons elem (parsed-seq* parser key-fn array-coerce-fn))))))
(cons elem (parsed-seq* p jp))))))

(defn parsed-seq
"Returns a lazy seq of Clojure objects corresponding to the JSON read from
@@ -330,11 +345,12 @@
([reader key-fn] (parsed-seq reader key-fn nil))
([^BufferedReader reader key-fn array-coerce-fn]
(when reader
(parsed-seq* (.createParser ^JsonFactory
(parsed-seq* (or *parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
(.createParser ^JsonFactory
(or factory/*json-factory*
factory/json-factory)
^Reader reader)
key-fn array-coerce-fn))))
^Reader reader)))))

(defn parsed-smile-seq
"Returns a lazy seq of Clojure objects corresponding to the SMILE read from
@@ -346,11 +362,12 @@
([reader key-fn] (parsed-smile-seq reader key-fn nil))
([^BufferedReader reader key-fn array-coerce-fn]
(when reader
(parsed-seq* (.createParser ^SmileFactory
(parsed-seq* (or *parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
(.createParser ^SmileFactory
(or factory/*smile-factory*
factory/smile-factory)
^Reader reader)
key-fn array-coerce-fn))))
^Reader reader)))))

;; aliases for clojure-json users
(defmacro copy-arglists
16 changes: 12 additions & 4 deletions src/cheshire/exact.clj
Original file line number Diff line number Diff line change
@@ -24,8 +24,12 @@
(when string
(let [jp (.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader (StringReader. string))]
(exact-parse jp (parse/parse jp key-fn nil array-coerce-fn))))))
^Reader (StringReader. string))
parsed (parse/parse (or core/*parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
jp
nil)]
(exact-parse jp parsed)))))

(defn parse-string-strict
([string] (parse-string-strict string nil nil))
@@ -34,8 +38,12 @@
(when string
(let [jp (.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Writer (StringReader. string))]
(exact-parse jp (parse/parse-strict jp key-fn nil array-coerce-fn))))))
^Writer (StringReader. string))
parsed (parse/parse-strict (or core/*parser*
(parse/backwards-compatible-parser key-fn array-coerce-fn))
jp
nil)]
(exact-parse jp parsed)))))

(def decode parse-string)
(core/copy-arglists decode parse-string)
Loading