From 30f4e4b56f5ade6ec8143a99885d8bc0228024c2 Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Thu, 18 Mar 2021 21:49:55 +0200 Subject: [PATCH 01/10] Create parsers via protocols --- src/cheshire/core.clj | 34 +++++++++------------------------- src/cheshire/parse.clj | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/cheshire/core.clj b/src/cheshire/core.clj index 8885c7b3..4fc717b7 100644 --- a/src/cheshire/core.clj +++ b/src/cheshire/core.clj @@ -10,7 +10,7 @@ (com.fasterxml.jackson.dataformat.cbor CBORFactory) (com.fasterxml.jackson.dataformat.smile SmileFactory) (cheshire.prettyprint CustomPrettyPrinter) - (java.io StringWriter StringReader BufferedReader BufferedWriter + (java.io StringWriter BufferedReader BufferedWriter ByteArrayOutputStream OutputStream Reader Writer))) (defonce default-pretty-print-options @@ -206,9 +206,7 @@ ([^String string key-fn array-coerce-fn] (when string (parse/parse - (.createParser ^JsonFactory (or factory/*json-factory* - factory/json-factory) - ^Reader (StringReader. string)) + (parse/json-parser string) key-fn nil array-coerce-fn)))) ;; Parsing strictly @@ -226,9 +224,7 @@ ([^String string key-fn array-coerce-fn] (when string (parse/parse-strict - (.createParser ^JsonFactory (or factory/*json-factory* - factory/json-factory) - ^Reader (StringReader. string)) + (parse/json-parser string) key-fn nil array-coerce-fn)))) (defn parse-stream @@ -250,9 +246,7 @@ ([^BufferedReader rdr key-fn array-coerce-fn] (when rdr (parse/parse - (.createParser ^JsonFactory (or factory/*json-factory* - factory/json-factory) - ^Reader rdr) + (parse/json-parser rdr) key-fn nil array-coerce-fn)))) (defn parse-stream-strict @@ -270,9 +264,7 @@ ([^BufferedReader rdr key-fn array-coerce-fn] (when rdr (parse/parse-strict - (.createParser ^JsonFactory (or factory/*json-factory* - factory/json-factory) - ^Reader rdr) + (parse/json-parser rdr) key-fn nil array-coerce-fn)))) (defn parse-smile @@ -287,8 +279,7 @@ ([^bytes bytes key-fn array-coerce-fn] (when bytes (parse/parse - (.createParser ^SmileFactory (or factory/*smile-factory* - factory/smile-factory) bytes) + (parse/smile-parser bytes) key-fn nil array-coerce-fn)))) (defn parse-cbor @@ -303,8 +294,7 @@ ([^bytes bytes key-fn array-coerce-fn] (when bytes (parse/parse - (.createParser ^CBORFactory (or factory/*cbor-factory* - factory/cbor-factory) bytes) + (parse/cbor-parser bytes) key-fn nil array-coerce-fn)))) (def ^{:doc "Object used to determine end of lazy parsing attempt."} @@ -330,10 +320,7 @@ ([reader key-fn] (parsed-seq reader key-fn nil)) ([^BufferedReader reader key-fn array-coerce-fn] (when reader - (parsed-seq* (.createParser ^JsonFactory - (or factory/*json-factory* - factory/json-factory) - ^Reader reader) + (parsed-seq* (parse/json-parser reader) key-fn array-coerce-fn)))) (defn parsed-smile-seq @@ -346,10 +333,7 @@ ([reader key-fn] (parsed-smile-seq reader key-fn nil)) ([^BufferedReader reader key-fn array-coerce-fn] (when reader - (parsed-seq* (.createParser ^SmileFactory - (or factory/*smile-factory* - factory/smile-factory) - ^Reader reader) + (parsed-seq* (parse/smile-parser reader) key-fn array-coerce-fn)))) ;; aliases for clojure-json users diff --git a/src/cheshire/parse.clj b/src/cheshire/parse.clj index 0dcc3ad2..81d66c08 100644 --- a/src/cheshire/parse.clj +++ b/src/cheshire/parse.clj @@ -1,5 +1,45 @@ (ns cheshire.parse - (:import (com.fasterxml.jackson.core JsonParser JsonToken))) + (:require [cheshire.factory :as factory]) + (:import (java.io Reader) + (com.fasterxml.jackson.core JsonFactory JsonParser JsonToken) + (com.fasterxml.jackson.dataformat.cbor CBORFactory) + (com.fasterxml.jackson.dataformat.smile SmileFactory))) + +(defprotocol ToJsonParser + (-json-parser [self ^JsonFactory factory])) + +(defprotocol ToCBORParser + (-cbor-parser [self ^CBORFactory factory])) + +(defprotocol ToSmileParser + (-smile-parser [self ^SmileFactory factory])) + +(extend-protocol ToJsonParser + String + (-json-parser [self ^JsonFactory factory] (.createParser factory self)) + + Reader + (-json-parser [self ^JsonFactory factory] (.createParser factory self))) + +(extend-protocol ToCBORParser + (Class/forName "[B") + (-cbor-parser [self ^CBORFactory factory] (.createParser factory self))) + +(extend-protocol ToSmileParser + (Class/forName "[B") + (-smile-parser [self ^SmileFactory factory] (.createParser factory self)) + + Reader + (-smile-parser [self ^SmileFactory factory] (.createParser factory self))) + +(defn json-parser [input] + (-json-parser input (or factory/*json-factory* factory/json-factory))) + +(defn cbor-parser [input] + (-cbor-parser input (or factory/*cbor-factory* factory/cbor-factory))) + +(defn smile-parser [input] + (-smile-parser input (or factory/*smile-factory* factory/smile-factory))) (declare parse*) From a39ff5766d0a0f21c5969a09eea6b5e7fa4094f4 Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Thu, 18 Mar 2021 23:22:05 +0200 Subject: [PATCH 02/10] Replace type hints with more protocol impls --- src/cheshire/core.clj | 12 +++++------ src/cheshire/parse.clj | 47 ++++++++++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/cheshire/core.clj b/src/cheshire/core.clj index 4fc717b7..16ea04be 100644 --- a/src/cheshire/core.clj +++ b/src/cheshire/core.clj @@ -243,7 +243,7 @@ see parsed-seq." ([rdr] (parse-stream rdr nil nil)) ([rdr key-fn] (parse-stream rdr key-fn nil)) - ([^BufferedReader rdr key-fn array-coerce-fn] + ([rdr key-fn array-coerce-fn] (when rdr (parse/parse (parse/json-parser rdr) @@ -261,7 +261,7 @@ Does not lazily parse top-level arrays." ([rdr] (parse-stream-strict rdr nil nil)) ([rdr key-fn] (parse-stream-strict rdr key-fn nil)) - ([^BufferedReader rdr key-fn array-coerce-fn] + ([rdr key-fn array-coerce-fn] (when rdr (parse/parse-strict (parse/json-parser rdr) @@ -276,7 +276,7 @@ and returning the collection to be used for array values." ([bytes] (parse-smile bytes nil nil)) ([bytes key-fn] (parse-smile bytes key-fn nil)) - ([^bytes bytes key-fn array-coerce-fn] + ([bytes key-fn array-coerce-fn] (when bytes (parse/parse (parse/smile-parser bytes) @@ -291,7 +291,7 @@ and returning the collection to be used for array values." ([bytes] (parse-cbor bytes nil nil)) ([bytes key-fn] (parse-cbor bytes key-fn nil)) - ([^bytes bytes key-fn array-coerce-fn] + ([bytes key-fn array-coerce-fn] (when bytes (parse/parse (parse/cbor-parser bytes) @@ -318,7 +318,7 @@ If non-laziness is needed, see parse-stream." ([reader] (parsed-seq reader nil nil)) ([reader key-fn] (parsed-seq reader key-fn nil)) - ([^BufferedReader reader key-fn array-coerce-fn] + ([reader key-fn array-coerce-fn] (when reader (parsed-seq* (parse/json-parser reader) key-fn array-coerce-fn)))) @@ -331,7 +331,7 @@ and returning the collection to be used for array values." ([reader] (parsed-smile-seq reader nil nil)) ([reader key-fn] (parsed-smile-seq reader key-fn nil)) - ([^BufferedReader reader key-fn array-coerce-fn] + ([reader key-fn array-coerce-fn] (when reader (parsed-seq* (parse/smile-parser reader) key-fn array-coerce-fn)))) diff --git a/src/cheshire/parse.clj b/src/cheshire/parse.clj index 81d66c08..8f2398af 100644 --- a/src/cheshire/parse.clj +++ b/src/cheshire/parse.clj @@ -1,6 +1,7 @@ (ns cheshire.parse (:require [cheshire.factory :as factory]) - (:import (java.io Reader) + (:import (java.io DataInput File InputStream Reader) + (java.net URL) (com.fasterxml.jackson.core JsonFactory JsonParser JsonToken) (com.fasterxml.jackson.dataformat.cbor CBORFactory) (com.fasterxml.jackson.dataformat.smile SmileFactory))) @@ -14,24 +15,48 @@ (defprotocol ToSmileParser (-smile-parser [self ^SmileFactory factory])) -(extend-protocol ToJsonParser - String - (-json-parser [self ^JsonFactory factory] (.createParser factory self)) +(defmacro extend-parser [Protocol method Factory & classes] + (let [factory (with-meta 'factory {:tag Factory})] + `(extend-protocol ~Protocol + ~@(mapcat + (fn [T] [T `(~method [~'self ~factory] ~'(.createParser factory self))]) + classes)))) - Reader +(extend-type (Class/forName "[B") + ToJsonParser (-json-parser [self ^JsonFactory factory] (.createParser factory self))) -(extend-protocol ToCBORParser - (Class/forName "[B") +(extend-type (Class/forName "[C") + ToJsonParser + (-json-parser [self ^JsonFactory factory] (.createParser factory self))) + +(extend-parser ToJsonParser -json-parser JsonFactory + DataInput + File + InputStream + Reader + String + URL) + +(extend-type (Class/forName "[B") + ToCBORParser (-cbor-parser [self ^CBORFactory factory] (.createParser factory self))) -(extend-protocol ToSmileParser - (Class/forName "[B") - (-smile-parser [self ^SmileFactory factory] (.createParser factory self)) +(extend-parser ToCBORParser -cbor-parser CBORFactory + File + InputStream + URL) - Reader +(extend-type (Class/forName "[B") + ToSmileParser (-smile-parser [self ^SmileFactory factory] (.createParser factory self))) +(extend-parser ToSmileParser -smile-parser SmileFactory + File + InputStream + URL + Reader) ; FIXME: Will actually parse JSON, not SMILE. Kept for backwards compatibility. + (defn json-parser [input] (-json-parser input (or factory/*json-factory* factory/json-factory))) From 8e16b3a2ff43af9ecbba71d0ad4fd0b7a399dd67 Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Fri, 19 Mar 2021 18:04:49 +0200 Subject: [PATCH 03/10] Reformatting to save lines --- src/cheshire/core.clj | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/cheshire/core.clj b/src/cheshire/core.clj index 16ea04be..cc780af6 100644 --- a/src/cheshire/core.clj +++ b/src/cheshire/core.clj @@ -205,9 +205,8 @@ ([string key-fn] (parse-string string key-fn nil)) ([^String string key-fn array-coerce-fn] (when string - (parse/parse - (parse/json-parser string) - key-fn nil array-coerce-fn)))) + (parse/parse (parse/json-parser string) + key-fn nil array-coerce-fn)))) ;; Parsing strictly (defn parse-string-strict @@ -223,9 +222,8 @@ ([string key-fn] (parse-string-strict string key-fn nil)) ([^String string key-fn array-coerce-fn] (when string - (parse/parse-strict - (parse/json-parser string) - key-fn nil array-coerce-fn)))) + (parse/parse-strict (parse/json-parser string) + key-fn nil array-coerce-fn)))) (defn parse-stream "Returns the Clojure object corresponding to the given reader, reader must @@ -245,9 +243,8 @@ ([rdr key-fn] (parse-stream rdr key-fn nil)) ([rdr key-fn array-coerce-fn] (when rdr - (parse/parse - (parse/json-parser rdr) - key-fn nil array-coerce-fn)))) + (parse/parse (parse/json-parser rdr) + key-fn nil array-coerce-fn)))) (defn parse-stream-strict "Returns the Clojure object corresponding to the given reader, reader must @@ -263,9 +260,8 @@ ([rdr key-fn] (parse-stream-strict rdr key-fn nil)) ([rdr key-fn array-coerce-fn] (when rdr - (parse/parse-strict - (parse/json-parser rdr) - key-fn nil array-coerce-fn)))) + (parse/parse-strict (parse/json-parser rdr) + key-fn nil array-coerce-fn)))) (defn parse-smile "Returns the Clojure object corresponding to the given SMILE-encoded bytes. @@ -278,9 +274,8 @@ ([bytes key-fn] (parse-smile bytes key-fn nil)) ([bytes key-fn array-coerce-fn] (when bytes - (parse/parse - (parse/smile-parser bytes) - key-fn nil array-coerce-fn)))) + (parse/parse (parse/smile-parser bytes) + key-fn nil array-coerce-fn)))) (defn parse-cbor "Returns the Clojure object corresponding to the given CBOR-encoded bytes. @@ -293,9 +288,8 @@ ([bytes key-fn] (parse-cbor bytes key-fn nil)) ([bytes key-fn array-coerce-fn] (when bytes - (parse/parse - (parse/cbor-parser bytes) - key-fn nil array-coerce-fn)))) + (parse/parse (parse/cbor-parser bytes) + key-fn nil array-coerce-fn)))) (def ^{:doc "Object used to determine end of lazy parsing attempt."} eof (Object.)) From cabbc572c4dbf8a6d01032bd4d8cbe476fe3c310 Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Fri, 19 Mar 2021 18:35:01 +0200 Subject: [PATCH 04/10] Add parse-json(-strict) and alias old fns to it --- src/cheshire/core.clj | 111 ++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 43 deletions(-) diff --git a/src/cheshire/core.clj b/src/cheshire/core.clj index cc780af6..ec60dfaa 100644 --- a/src/cheshire/core.clj +++ b/src/cheshire/core.clj @@ -13,6 +13,10 @@ (java.io StringWriter BufferedReader BufferedWriter ByteArrayOutputStream OutputStream Reader Writer))) +(defmacro copy-arglists + [dst src] + `(alter-meta! (var ~dst) merge (select-keys (meta (var ~src)) [:arglists]))) + (defonce default-pretty-print-options {:indentation " " :line-break "\n" @@ -191,7 +195,45 @@ (.toByteArray baos)))) ;; Parsers -(defn parse-string + +(defn parse-json + "Returns the Clojure object corresponding to the given JSON-encoded input. + The input can be a String, a Reader, an InputStream, a DataInput, a File, + a URL, a char array or a byte array. + An optional key-fn argument can be either true (to coerce keys to keywords), + false to leave them as strings, or a function to provide custom coercion. + + The array-coerce-fn is an optional function taking the name of an array field, + and returning the collection to be used for array values. + + If the top-level object is an array, it will be parsed lazily (use + `parse-json-strict' if strict parsing is required for top-level arrays." + ([input] (parse-json input nil nil)) + ([input key-fn] (parse-json input key-fn nil)) + ([input key-fn array-coerce-fn] + (when input + (parse/parse (parse/json-parser input) + key-fn nil array-coerce-fn)))) + +(defn parse-json-strict + "Returns the Clojure object corresponding to the given JSON-encoded input. + The input can be a String, a Reader, an InputStream, a DataInput, a File, + a URL, a char array or a byte array. + An optional key-fn argument can be either true (to coerce keys to keywords), + false to leave them as strings, or a function to provide custom coercion. + + The array-coerce-fn is an optional function taking the name of an array field, + and returning the collection to be used for array values. + + Does not lazily parse top-level arrays." + ([input] (parse-json-strict input nil nil)) + ([input key-fn] (parse-json-strict input key-fn nil)) + ([input key-fn array-coerce-fn] + (when input + (parse/parse-strict (parse/json-parser input) + key-fn nil array-coerce-fn)))) + +(def 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), false to leave them as strings, or a function to provide custom coercion. @@ -201,15 +243,11 @@ If the top-level object is an array, it will be parsed lazily (use `parse-strict' if strict parsing is required for top-level arrays." - ([string] (parse-string string nil nil)) - ([string key-fn] (parse-string string key-fn nil)) - ([^String string key-fn array-coerce-fn] - (when string - (parse/parse (parse/json-parser string) - key-fn nil array-coerce-fn)))) + parse-json) +(copy-arglists parse-string parse-json) ;; Parsing strictly -(defn parse-string-strict +(def parse-string-strict "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), false to leave them as strings, or a function to provide custom coercion. @@ -218,14 +256,10 @@ and returning the collection to be used for array values. Does not lazily parse top-level arrays." - ([string] (parse-string-strict string nil nil)) - ([string key-fn] (parse-string-strict string key-fn nil)) - ([^String string key-fn array-coerce-fn] - (when string - (parse/parse-strict (parse/json-parser string) - key-fn nil array-coerce-fn)))) + parse-json-strict) +(copy-arglists parse-string-strict parse-json-strict) -(defn parse-stream +(def parse-stream "Returns the Clojure object corresponding to the given reader, reader must implement BufferedReader. An optional key-fn argument can be either true (to coerce keys to keywords),false to leave them as strings, or a function to @@ -239,14 +273,10 @@ If multiple objects (enclosed in a top-level `{}' need to be parsed lazily, see parsed-seq." - ([rdr] (parse-stream rdr nil nil)) - ([rdr key-fn] (parse-stream rdr key-fn nil)) - ([rdr key-fn array-coerce-fn] - (when rdr - (parse/parse (parse/json-parser rdr) - key-fn nil array-coerce-fn)))) + parse-json) +(copy-arglists parse-stream parse-json) -(defn parse-stream-strict +(def parse-stream-strict "Returns the Clojure object corresponding to the given reader, reader must implement BufferedReader. An optional key-fn argument can be either true (to coerce keys to keywords),false to leave them as strings, or a function to @@ -256,15 +286,12 @@ and returning the collection to be used for array values. Does not lazily parse top-level arrays." - ([rdr] (parse-stream-strict rdr nil nil)) - ([rdr key-fn] (parse-stream-strict rdr key-fn nil)) - ([rdr key-fn array-coerce-fn] - (when rdr - (parse/parse-strict (parse/json-parser rdr) - key-fn nil array-coerce-fn)))) + parse-json-strict) +(copy-arglists parse-stream-strict parse-json-strict) (defn parse-smile "Returns the Clojure object corresponding to the given SMILE-encoded bytes. + The bytes can be an InputStream, a File, a URL or a byte array. An optional key-fn argument can be either true (to coerce keys to keywords), false to leave them as strings, or a function to provide custom coercion. @@ -278,7 +305,8 @@ key-fn nil array-coerce-fn)))) (defn parse-cbor - "Returns the Clojure object corresponding to the given CBOR-encoded bytes. + "Returns the Clojure object corresponding to the given CBOR-encoded bytes. + The bytes can be an InputStream, a File, a URL or a byte array. An optional key-fn argument can be either true (to coerce keys to keywords), false to leave them as strings, or a function to provide custom coercion. @@ -305,16 +333,16 @@ (defn parsed-seq "Returns a lazy seq of Clojure objects corresponding to the JSON read from - the given reader. The seq continues until the end of the reader is reached. + the given input. The seq continues until the end of the input is reached. The array-coerce-fn is an optional function taking the name of an array field, and returning the collection to be used for array values. If non-laziness is needed, see parse-stream." - ([reader] (parsed-seq reader nil nil)) - ([reader key-fn] (parsed-seq reader key-fn nil)) - ([reader key-fn array-coerce-fn] - (when reader - (parsed-seq* (parse/json-parser reader) + ([input] (parsed-seq input nil nil)) + ([input key-fn] (parsed-seq input key-fn nil)) + ([input key-fn array-coerce-fn] + (when input + (parsed-seq* (parse/json-parser input) key-fn array-coerce-fn)))) (defn parsed-smile-seq @@ -323,17 +351,14 @@ The array-coerce-fn is an optional function taking the name of an array field, and returning the collection to be used for array values." - ([reader] (parsed-smile-seq reader nil nil)) - ([reader key-fn] (parsed-smile-seq reader key-fn nil)) - ([reader key-fn array-coerce-fn] - (when reader - (parsed-seq* (parse/smile-parser reader) + ([input] (parsed-smile-seq input nil nil)) + ([input key-fn] (parsed-smile-seq input key-fn nil)) + ([input key-fn array-coerce-fn] + (when input + (parsed-seq* (parse/smile-parser input) key-fn array-coerce-fn)))) ;; aliases for clojure-json users -(defmacro copy-arglists - [dst src] - `(alter-meta! (var ~dst) merge (select-keys (meta (var ~src)) [:arglists]))) (def encode "Alias to generate-string for clojure-json users" generate-string) (copy-arglists encode generate-string) (def encode-stream "Alias to generate-stream for clojure-json users" generate-stream) From d4d0a5459d8792f85853855c72d3de6861c8ad72 Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Fri, 19 Mar 2021 18:41:15 +0200 Subject: [PATCH 05/10] Fix array reflection warnings --- src/cheshire/parse.clj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cheshire/parse.clj b/src/cheshire/parse.clj index 8f2398af..f1bd2df1 100644 --- a/src/cheshire/parse.clj +++ b/src/cheshire/parse.clj @@ -24,11 +24,11 @@ (extend-type (Class/forName "[B") ToJsonParser - (-json-parser [self ^JsonFactory factory] (.createParser factory self))) + (-json-parser [self ^JsonFactory factory] (.createParser factory ^"[B" self))) (extend-type (Class/forName "[C") ToJsonParser - (-json-parser [self ^JsonFactory factory] (.createParser factory self))) + (-json-parser [self ^JsonFactory factory] (.createParser factory ^"[C" self))) (extend-parser ToJsonParser -json-parser JsonFactory DataInput @@ -40,7 +40,7 @@ (extend-type (Class/forName "[B") ToCBORParser - (-cbor-parser [self ^CBORFactory factory] (.createParser factory self))) + (-cbor-parser [self ^CBORFactory factory] (.createParser factory ^"[B" self))) (extend-parser ToCBORParser -cbor-parser CBORFactory File @@ -49,7 +49,7 @@ (extend-type (Class/forName "[B") ToSmileParser - (-smile-parser [self ^SmileFactory factory] (.createParser factory self))) + (-smile-parser [self ^SmileFactory factory] (.createParser factory ^"[B" self))) (extend-parser ToSmileParser -smile-parser SmileFactory File From ac54f614cb2ae23e84d6238d4f4350ae090a346d Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Fri, 19 Mar 2021 18:43:57 +0200 Subject: [PATCH 06/10] Fix #175 (SMILE Reader) --- src/cheshire/core.clj | 2 +- src/cheshire/parse.clj | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cheshire/core.clj b/src/cheshire/core.clj index ec60dfaa..6106203b 100644 --- a/src/cheshire/core.clj +++ b/src/cheshire/core.clj @@ -347,7 +347,7 @@ (defn parsed-smile-seq "Returns a lazy seq of Clojure objects corresponding to the SMILE read from - the given reader. The seq continues until the end of the reader is reached. + the given input. The seq continues until the end of the input is reached. The array-coerce-fn is an optional function taking the name of an array field, and returning the collection to be used for array values." diff --git a/src/cheshire/parse.clj b/src/cheshire/parse.clj index f1bd2df1..1f923e1e 100644 --- a/src/cheshire/parse.clj +++ b/src/cheshire/parse.clj @@ -54,8 +54,7 @@ (extend-parser ToSmileParser -smile-parser SmileFactory File InputStream - URL - Reader) ; FIXME: Will actually parse JSON, not SMILE. Kept for backwards compatibility. + URL) (defn json-parser [input] (-json-parser input (or factory/*json-factory* factory/json-factory))) From 9d5c3d75a2dcc15e014be50ac105548f2418bebd Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Fri, 19 Mar 2021 18:53:26 +0200 Subject: [PATCH 07/10] Reorder extends --- src/cheshire/parse.clj | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/cheshire/parse.clj b/src/cheshire/parse.clj index 1f923e1e..bee97e6e 100644 --- a/src/cheshire/parse.clj +++ b/src/cheshire/parse.clj @@ -22,40 +22,40 @@ (fn [T] [T `(~method [~'self ~factory] ~'(.createParser factory self))]) classes)))) -(extend-type (Class/forName "[B") - ToJsonParser - (-json-parser [self ^JsonFactory factory] (.createParser factory ^"[B" self))) +(extend-parser ToJsonParser -json-parser JsonFactory + String + Reader + InputStream + DataInput + File + URL) (extend-type (Class/forName "[C") ToJsonParser (-json-parser [self ^JsonFactory factory] (.createParser factory ^"[C" self))) -(extend-parser ToJsonParser -json-parser JsonFactory - DataInput - File +(extend-type (Class/forName "[B") + ToJsonParser + (-json-parser [self ^JsonFactory factory] (.createParser factory ^"[B" self))) + +(extend-parser ToCBORParser -cbor-parser CBORFactory InputStream - Reader - String + File URL) (extend-type (Class/forName "[B") ToCBORParser (-cbor-parser [self ^CBORFactory factory] (.createParser factory ^"[B" self))) -(extend-parser ToCBORParser -cbor-parser CBORFactory - File +(extend-parser ToSmileParser -smile-parser SmileFactory InputStream + File URL) (extend-type (Class/forName "[B") ToSmileParser (-smile-parser [self ^SmileFactory factory] (.createParser factory ^"[B" self))) -(extend-parser ToSmileParser -smile-parser SmileFactory - File - InputStream - URL) - (defn json-parser [input] (-json-parser input (or factory/*json-factory* factory/json-factory))) From d973497f3160a3a69bfd6c341cbb7414d003e00f Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Mon, 22 Mar 2021 20:11:43 +0200 Subject: [PATCH 08/10] Actually, let's make use of the old type information --- src/cheshire/core.clj | 78 ++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/src/cheshire/core.clj b/src/cheshire/core.clj index 6106203b..a31ce7b6 100644 --- a/src/cheshire/core.clj +++ b/src/cheshire/core.clj @@ -13,10 +13,6 @@ (java.io StringWriter BufferedReader BufferedWriter ByteArrayOutputStream OutputStream Reader Writer))) -(defmacro copy-arglists - [dst src] - `(alter-meta! (var ~dst) merge (select-keys (meta (var ~src)) [:arglists]))) - (defonce default-pretty-print-options {:indentation " " :line-break "\n" @@ -233,7 +229,7 @@ (parse/parse-strict (parse/json-parser input) key-fn nil array-coerce-fn)))) -(def parse-string +(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), false to leave them as strings, or a function to provide custom coercion. @@ -243,11 +239,18 @@ If the top-level object is an array, it will be parsed lazily (use `parse-strict' if strict parsing is required for top-level arrays." - parse-json) -(copy-arglists parse-string parse-json) + ([string] (parse-string string nil nil)) + ([string key-fn] (parse-string string key-fn nil)) + ([^String string key-fn array-coerce-fn] + (when string + (parse/parse + (.createParser ^JsonFactory (or factory/*json-factory* + factory/json-factory) + string) + key-fn nil array-coerce-fn)))) ;; Parsing strictly -(def parse-string-strict +(defn parse-string-strict "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), false to leave them as strings, or a function to provide custom coercion. @@ -256,14 +259,20 @@ and returning the collection to be used for array values. Does not lazily parse top-level arrays." - parse-json-strict) -(copy-arglists parse-string-strict parse-json-strict) - -(def parse-stream - "Returns the Clojure object corresponding to the given reader, reader must - implement BufferedReader. An optional key-fn argument can be either true (to - coerce keys to keywords),false to leave them as strings, or a function to - provide custom coercion. + ([string] (parse-string-strict string nil nil)) + ([string key-fn] (parse-string-strict string key-fn nil)) + ([^String string key-fn array-coerce-fn] + (when string + (parse/parse-strict + (.createParser ^JsonFactory (or factory/*json-factory* + factory/json-factory) + string) + key-fn nil array-coerce-fn)))) + +(defn parse-stream + "Returns the Clojure object corresponding to the given Reader. + An optional key-fn argument can be either true (to coerce keys to keywords), + false to leave them as strings, or a function to provide custom coercion. The array-coerce-fn is an optional function taking the name of an array field, and returning the collection to be used for array values. @@ -273,21 +282,34 @@ If multiple objects (enclosed in a top-level `{}' need to be parsed lazily, see parsed-seq." - parse-json) -(copy-arglists parse-stream parse-json) - -(def parse-stream-strict - "Returns the Clojure object corresponding to the given reader, reader must - implement BufferedReader. An optional key-fn argument can be either true (to - coerce keys to keywords),false to leave them as strings, or a function to - provide custom coercion. + ([rdr] (parse-stream rdr nil nil)) + ([rdr key-fn] (parse-stream rdr key-fn nil)) + ([^Reader rdr key-fn array-coerce-fn] + (when rdr + (parse/parse + (.createParser ^JsonFactory (or factory/*json-factory* + factory/json-factory) + rdr) + key-fn nil array-coerce-fn)))) + +(defn parse-stream-strict + "Returns the Clojure object corresponding to the given Reader. + An optional key-fn argument can be either true (to coerce keys to keywords), + false to leave them as strings, or a function to provide custom coercion. The array-coerce-fn is an optional function taking the name of an array field, and returning the collection to be used for array values. Does not lazily parse top-level arrays." - parse-json-strict) -(copy-arglists parse-stream-strict parse-json-strict) + ([rdr] (parse-stream rdr nil nil)) + ([rdr key-fn] (parse-stream rdr key-fn nil)) + ([^Reader rdr key-fn array-coerce-fn] + (when rdr + (parse/parse-strict + (.createParser ^JsonFactory (or factory/*json-factory* + factory/json-factory) + rdr) + key-fn nil array-coerce-fn)))) (defn parse-smile "Returns the Clojure object corresponding to the given SMILE-encoded bytes. @@ -358,6 +380,10 @@ (parsed-seq* (parse/smile-parser input) key-fn array-coerce-fn)))) +(defmacro copy-arglists + [dst src] + `(alter-meta! (var ~dst) merge (select-keys (meta (var ~src)) [:arglists]))) + ;; aliases for clojure-json users (def encode "Alias to generate-string for clojure-json users" generate-string) (copy-arglists encode generate-string) From 4d8b726f7fc036aead1ec33471d9990a6d9bc7ca Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Mon, 22 Mar 2021 20:13:52 +0200 Subject: [PATCH 09/10] Remove obsoleted import --- src/cheshire/core.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cheshire/core.clj b/src/cheshire/core.clj index a31ce7b6..296e4801 100644 --- a/src/cheshire/core.clj +++ b/src/cheshire/core.clj @@ -10,7 +10,7 @@ (com.fasterxml.jackson.dataformat.cbor CBORFactory) (com.fasterxml.jackson.dataformat.smile SmileFactory) (cheshire.prettyprint CustomPrettyPrinter) - (java.io StringWriter BufferedReader BufferedWriter + (java.io StringWriter BufferedWriter ByteArrayOutputStream OutputStream Reader Writer))) (defonce default-pretty-print-options From 5e5ec02aa2a3d661bd1350dab42707b30bfca171 Mon Sep 17 00:00:00 2001 From: Pauli Jaakkola Date: Mon, 22 Mar 2021 20:17:10 +0200 Subject: [PATCH 10/10] Revert some erroneous and superflous changes --- src/cheshire/core.clj | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/cheshire/core.clj b/src/cheshire/core.clj index 296e4801..095c9a8a 100644 --- a/src/cheshire/core.clj +++ b/src/cheshire/core.clj @@ -244,10 +244,10 @@ ([^String string key-fn array-coerce-fn] (when string (parse/parse - (.createParser ^JsonFactory (or factory/*json-factory* - factory/json-factory) - string) - key-fn nil array-coerce-fn)))) + (.createParser ^JsonFactory (or factory/*json-factory* + factory/json-factory) + string) + key-fn nil array-coerce-fn)))) ;; Parsing strictly (defn parse-string-strict @@ -264,10 +264,10 @@ ([^String string key-fn array-coerce-fn] (when string (parse/parse-strict - (.createParser ^JsonFactory (or factory/*json-factory* - factory/json-factory) - string) - key-fn nil array-coerce-fn)))) + (.createParser ^JsonFactory (or factory/*json-factory* + factory/json-factory) + string) + key-fn nil array-coerce-fn)))) (defn parse-stream "Returns the Clojure object corresponding to the given Reader. @@ -287,10 +287,10 @@ ([^Reader rdr key-fn array-coerce-fn] (when rdr (parse/parse - (.createParser ^JsonFactory (or factory/*json-factory* - factory/json-factory) - rdr) - key-fn nil array-coerce-fn)))) + (.createParser ^JsonFactory (or factory/*json-factory* + factory/json-factory) + rdr) + key-fn nil array-coerce-fn)))) (defn parse-stream-strict "Returns the Clojure object corresponding to the given Reader. @@ -301,15 +301,15 @@ and returning the collection to be used for array values. Does not lazily parse top-level arrays." - ([rdr] (parse-stream rdr nil nil)) - ([rdr key-fn] (parse-stream rdr key-fn nil)) + ([rdr] (parse-stream-strict rdr nil nil)) + ([rdr key-fn] (parse-stream-strict rdr key-fn nil)) ([^Reader rdr key-fn array-coerce-fn] (when rdr (parse/parse-strict - (.createParser ^JsonFactory (or factory/*json-factory* - factory/json-factory) - rdr) - key-fn nil array-coerce-fn)))) + (.createParser ^JsonFactory (or factory/*json-factory* + factory/json-factory) + rdr) + key-fn nil array-coerce-fn)))) (defn parse-smile "Returns the Clojure object corresponding to the given SMILE-encoded bytes. @@ -380,11 +380,10 @@ (parsed-seq* (parse/smile-parser input) key-fn array-coerce-fn)))) +;; aliases for clojure-json users (defmacro copy-arglists [dst src] `(alter-meta! (var ~dst) merge (select-keys (meta (var ~src)) [:arglists]))) - -;; aliases for clojure-json users (def encode "Alias to generate-string for clojure-json users" generate-string) (copy-arglists encode generate-string) (def encode-stream "Alias to generate-stream for clojure-json users" generate-stream)