Skip to content

Commit

Permalink
Add read (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude authored Jul 15, 2023
1 parent 250f2b1 commit 1564dd9
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 21 deletions.
27 changes: 20 additions & 7 deletions src/babashka/json.clj
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
(ns babashka.json)
(ns babashka.json
(:refer-clojure :exclude [read]))

(defn try-require [sym]
(defn- try-require [sym]
(try (deref (requiring-resolve sym))
(catch Exception _e
nil)))

(let [provider (some-> (System/getProperty "babashka.json.provider")
not-empty symbol)
[lib read-fn write-fn]
[lib read-str-fn write-str-fn ->json-reader read-fn]
(if provider
(deref (requiring-resolve
(case provider
Expand All @@ -29,18 +30,30 @@
;; this one should always work as this project has a dependency on it.
(try-require 'babashka.json.internal.data-json/fns)))]
(def ^:private lib lib)
(def ^:private read-fn read-fn)
(def ^:private write-fn write-fn))
(def ^:private read-str-fn read-str-fn)
(def ^:private write-str-fn write-str-fn)
(def ^:private internal->json-reader ->json-reader)
(def ^:private read-fn read-fn))

(defn read
([reader] (read reader nil))
([reader opts]
(read-fn reader opts)))

(defn read-str
([s] (read-str s nil))
([s opts]
(read-fn s opts)))
(read-str-fn s opts)))

(defn write-str
([s] (write-str s nil))
([s opts]
(write-fn s opts)))
(write-str-fn s opts)))

(defn ->json-reader
([x] (->json-reader x nil))
([x _opts]
(internal->json-reader x)))

(defn get-provider
"Returns which library currently provides the JSON implementation."
Expand Down
18 changes: 16 additions & 2 deletions src/babashka/json/internal/charred.clj
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
(ns babashka.json.internal.charred
(:require [charred.api :as json]))
(:require [charred.api :as json])
(:refer-clojure :exclude [read])
(:import [charred CloseableSupplier]))

(set! *warn-on-reflection* true)

(defn ->json-reader
([x] (->json-reader x nil))
([x {:keys [key-fn] :or {key-fn keyword}}]
(json/read-json-supplier x {:key-fn key-fn})))

(defn read
([reader] (read reader nil))
([reader _]
(.get ^CloseableSupplier reader)))

(defn read-str
([s] (read-str s nil))
Expand All @@ -9,4 +23,4 @@
([s] (write-str s nil))
([s _opts] (json/write-json-str s)))

(def fns ['com.cnuernber/charred read-str write-str])
(def fns ['com.cnuernber/charred read-str write-str ->json-reader read])
21 changes: 19 additions & 2 deletions src/babashka/json/internal/cheshire.clj
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
(ns babashka.json.internal.cheshire
(:require [cheshire.core :as cheshire]))
(:require [cheshire.core :as cheshire]
[cheshire.factory :as factory]
[cheshire.parse :as cheshire-parse])
(:refer-clojure :exclude [read])
(:import [com.fasterxml.jackson.core JsonFactory]
[java.io Reader]))

(defn read-str
([s] (read-str s nil))
Expand All @@ -9,4 +14,16 @@
([s] (write-str s nil))
([s _opts] (cheshire/generate-string s)))

(def fns ['cheshire/cheshire read-str write-str])
(defn ->json-reader
([rdr] (->json-reader rdr nil))
([rdr _opts]
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader rdr)))

(defn read
([reader] (read reader nil))
([reader _opts]
(cheshire-parse/parse-strict reader true nil nil)))

(def fns ['cheshire/cheshire read-str write-str ->json-reader read])
12 changes: 10 additions & 2 deletions src/babashka/json/internal/data_json.clj
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
(ns babashka.json.internal.data-json
(:require [clojure.data.json :as json]))
(:require [clojure.data.json :as json])
(:refer-clojure :exclude [read]))

(defn read
([reader] (read reader nil))
([reader {:keys [key-fn]}]
(json/read reader :key-fn (or key-fn keyword))))

(defn read-str
([s] (read-str s nil))
Expand All @@ -9,4 +15,6 @@
([s] (write-str s nil))
([s _opts] (json/write-str s)))

(def fns ['org.clojure/data.json read-str write-str])
(defn ->json-reader [x & _xs] x)

(def fns ['org.clojure/data.json read-str write-str ->json-reader read])
30 changes: 23 additions & 7 deletions src/babashka/json/internal/jsonista.clj
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
(ns babashka.json.internal.jsonista
(:require [jsonista.core :as j]))
(:require [jsonista.core :as json])
(:refer-clojure :exclude [read])
(:import))

(set! *warn-on-reflection* true)

(defn- -key-fn->object-mapper
[key-fn]
^com.fasterxml.jackson.databind.ObjectMapper [key-fn]
(if-not key-fn
j/default-object-mapper
(j/object-mapper {:decode-key-fn key-fn})))
json/default-object-mapper
(json/object-mapper {:decode-key-fn key-fn})))

(defn ->json-reader
([reader] (->json-reader reader nil))
([reader {:keys [key-fn] :or {key-fn keyword}}]
(-> (-key-fn->object-mapper key-fn)
.getFactory
(.createParser ^java.io.Reader reader))))

(defn read
([s] (read s nil))
([s _ #_{:keys [key-fn] :or {key-fn keyword}}]
(.readValueAs ^com.fasterxml.jackson.core.json.ReaderBasedJsonParser s Object)))

(defn read-str
([s] (read-str s nil))
([s {:keys [key-fn] :or {key-fn keyword}}]
(j/read-value s (-key-fn->object-mapper key-fn))))
(json/read-value s (-key-fn->object-mapper key-fn))))

(defn write-str
([s] (write-str s nil))
([s _opts] (j/write-value-as-string s (-key-fn->object-mapper nil))))
([s _opts] (json/write-value-as-string s (-key-fn->object-mapper nil))))

(def fns ['metosin/jsonista read-str write-str])
(def fns ['metosin/jsonista read-str write-str ->json-reader read])
7 changes: 6 additions & 1 deletion test/babashka/json_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
[clojure.test :refer [deftest is testing]]))

(deftest json-test
(println "Testing provider" (json/get-provider))
(testing "read json"
(is (= [1 2 3] (json/read-str "[1, 2, 3]")))
(is (= {:a 1} (json/read-str "{\"a\": 1}")))
(is (= {:a 1} (json/read-str "{\"a\": 1}" {:key-fn keyword})))
(is (= {"a" 1} (json/read-str "{\"a\": 1}" {:key-fn str}))))
(testing "write json"
(is (= [1 2 3] (json/read-str (json/write-str [1 2 3]))))
(is (= {:a 1} (json/read-str (json/write-str {:a 1}))))))
(is (= {:a 1} (json/read-str (json/write-str {:a 1})))))
(testing "read json"
(let [rdr (json/->json-reader (java.io.StringReader. "{\"a\": 1} {\"b\": 2}"))]
(is (= {:a 1} (json/read rdr)))
#_(is (= {:b 2} (json/read rdr))))))

(deftest provider-test
(let [prop (some-> (System/getProperty "babashka.json.provider") not-empty symbol)]
Expand Down

0 comments on commit 1564dd9

Please sign in to comment.