diff --git a/src/babashka/pods.clj b/src/babashka/pods.clj index 77a9ae2..a4bb820 100644 --- a/src/babashka/pods.clj +++ b/src/babashka/pods.clj @@ -15,8 +15,11 @@ ([pod-id-or-pod sym args] (invoke pod-id-or-pod sym args {})) ([pod-id-or-pod sym args opts] (jvm/invoke pod-id-or-pod sym args opts))) -(defn add-transit-read-handler [tag fn] - (jvm/add-transit-read-handler tag fn)) +(defn add-transit-read-handler! [tag fn] + (jvm/add-transit-read-handler! tag fn)) -(defn add-transit-write-handler [tag fn classes] - (jvm/add-transit-write-handler tag fn classes)) +(defn add-transit-write-handler! [tag fn classes] + (jvm/add-transit-write-handler! tag fn classes)) + +(defn set-transit-default-write-handler! [tag-fn val-fn] + (jvm/set-transit-default-write-handler! tag-fn val-fn)) diff --git a/src/babashka/pods/impl.clj b/src/babashka/pods/impl.clj index f535ad7..ecedc94 100644 --- a/src/babashka/pods/impl.clj +++ b/src/babashka/pods/impl.clj @@ -54,11 +54,12 @@ (transit/read r)))) ;; https://www.cognitect.com/blog/2015/9/10/extending-transit -(defn add-transit-read-handler [tag fn] - (let [rh (transit/read-handler fn)] - (swap! transit-read-handlers assoc-in [*pod-id* tag] rh) - (update-transit-read-handler-map) - nil)) +(defn add-transit-read-handler! + ([tag fn] + (let [rh (transit/read-handler fn)] + (swap! transit-read-handlers assoc-in [*pod-id* tag] rh) + (update-transit-read-handler-map) + nil))) (defonce transit-write-handlers (atom {})) (defonce transit-write-handler-maps (atom {})) @@ -68,16 +69,23 @@ (transit/write-handler-map (get @transit-write-handlers *pod-id*)))) ;; https://www.cognitect.com/blog/2015/9/10/extending-transit -(defn add-transit-write-handler [tag fn classes] +(defn add-transit-write-handler! [tag fn classes] (let [rh (transit/write-handler tag fn)] (doseq [class classes] (swap! transit-write-handlers assoc-in [*pod-id* class] rh))) (update-transit-write-handler-map) nil) +(defonce transit-default-write-handlers (atom {})) + +(defn set-transit-default-write-handler! [tag-fn val-fn] + (let [wh (transit/write-handler tag-fn val-fn)] + (swap! transit-default-write-handlers assoc *pod-id* wh))) + (defn transit-json-write [pod-id ^String s] (with-open [baos (java.io.ByteArrayOutputStream. 4096)] - (let [w (transit/writer baos :json {:handlers (get @transit-write-handler-maps pod-id)})] + (let [w (transit/writer baos :json {:handlers (get @transit-write-handler-maps pod-id) + :default-handler (get @transit-default-write-handlers pod-id)})] (transit/write w s) (str baos)))) diff --git a/src/babashka/pods/jvm.clj b/src/babashka/pods/jvm.clj index 9c4a023..d93e815 100644 --- a/src/babashka/pods/jvm.clj +++ b/src/babashka/pods/jvm.clj @@ -71,8 +71,11 @@ ([pod-id sym args] (invoke pod-id sym args {})) ([pod-id sym args opts] (impl/invoke-public pod-id sym args opts))) -(defn add-transit-read-handler [tag fn] - (impl/add-transit-read-handler tag fn)) +(defn add-transit-read-handler! [tag fn] + (impl/add-transit-read-handler! tag fn)) -(defn add-transit-write-handler [tag fn classes] - (impl/add-transit-write-handler tag fn classes)) +(defn add-transit-write-handler! [tag fn classes] + (impl/add-transit-write-handler! tag fn classes)) + +(defn set-transit-default-write-handler! [tag-fn val-fn] + (impl/set-transit-default-write-handler! tag-fn val-fn)) diff --git a/src/babashka/pods/sci.clj b/src/babashka/pods/sci.clj index 7e85f63..10e62bb 100644 --- a/src/babashka/pods/sci.clj +++ b/src/babashka/pods/sci.clj @@ -81,8 +81,11 @@ ([pod-id sym args] (invoke pod-id sym args {})) ([pod-id sym args opts] (impl/invoke-public pod-id sym args opts))) -(defn add-transit-read-handler [tag fn] - (impl/add-transit-read-handler tag fn)) +(defn add-transit-read-handler! [tag fn] + (impl/add-transit-read-handler! tag fn)) -(defn add-transit-write-handler [tag fn classes] - (impl/add-transit-write-handler tag fn classes)) +(defn add-transit-write-handler! [tag fn classes] + (impl/add-transit-write-handler! tag fn classes)) + +(defn set-transit-default-write-handler! [tag-fn val-fn] + (impl/set-transit-default-write-handler! tag-fn val-fn)) diff --git a/test-pod/pod/test_pod.clj b/test-pod/pod/test_pod.clj index 48cc3c9..3c68680 100644 --- a/test-pod/pod/test_pod.clj +++ b/test-pod/pod/test_pod.clj @@ -40,7 +40,11 @@ {"local-date-time" (transit/read-handler (fn [s] - (java.time.LocalDateTime/parse s)))}})] + (java.time.LocalDateTime/parse s))) + "java.array" + (transit/read-handler + (fn [v] + (into-array v)))}})] (transit/read r)))) (defn transit-json-write [s] @@ -49,7 +53,11 @@ {java.time.LocalDateTime (transit/write-handler "local-date-time" - str)}})] + str)} + :default-handler + (transit/write-handler + (fn [x] (when (.isArray (class x)) "java.array")) + vec)})] (transit/write w s) (str baos)))) @@ -121,14 +129,26 @@ {"name" "read-other-tag" "code" "(defn read-other-tag [x] [x x])"} {"name" "-local-date-time"} - {"name" "local-date-time" + {"name" "transit-stuff" "code" " -(babashka.pods/add-transit-read-handler \"local-date-time\" +(babashka.pods/add-transit-read-handler! \"local-date-time\" (fn [s] (java.time.LocalDateTime/parse s))) -(babashka.pods/add-transit-write-handler \"local-date-time\" + +(babashka.pods/add-transit-write-handler! \"local-date-time\" str #{java.time.LocalDateTime}) + (defn local-date-time [x] - (-local-date-time x))"}] + (-local-date-time x)) + +;; serialize Java arrays as vectors with tag java.array +(babashka.pods/set-transit-default-write-handler! + (fn [x] (when (.isArray (class x)) \"java.array\")) + vec) + +(babashka.pods/add-transit-read-handler! \"java.array\" + into-array) + +"}] dependents)} {"name" "pod.test-pod.loaded" "defer" "true"} diff --git a/test-resources/test_program.clj b/test-resources/test_program.clj index 476e294..bb728a6 100644 --- a/test-resources/test_program.clj +++ b/test-resources/test_program.clj @@ -74,6 +74,12 @@ (instance? java.time.LocalDateTime (pod.test-pod/local-date-time (java.time.LocalDateTime/now))) true)) +(def assoc-string-array + (if (= "transit+json" fmt) + (let [v (:a (pod.test-pod/assoc {} :a (into-array String ["foo"])))] + (.isArray (class v))) + true)) + (require '[pod.test-pod.only-code :as only-code]) (def should-be-1 (only-code/foo)) @@ -101,4 +107,5 @@ loaded fn-called local-date-time + assoc-string-array should-be-1] diff --git a/test/babashka/pods/sci_test.clj b/test/babashka/pods/sci_test.clj index bdbe1e2..f5543c2 100644 --- a/test/babashka/pods/sci_test.clj +++ b/test/babashka/pods/sci_test.clj @@ -14,10 +14,12 @@ (apply pods/load-pod @ctx-ref args)) 'invoke pods/invoke 'unload-pod pods/unload-pod - 'add-transit-read-handler pods/add-transit-read-handler - 'add-transit-write-handler pods/add-transit-write-handler}} + 'add-transit-read-handler! pods/add-transit-read-handler! + 'add-transit-write-handler! pods/add-transit-write-handler! + 'set-transit-default-write-handler! pods/set-transit-default-write-handler!}} :classes {'System System - 'java.time.LocalDateTime java.time.LocalDateTime}}) + 'java.time.LocalDateTime java.time.LocalDateTime + 'java.lang.Class Class}}) _ (vreset! ctx-ref ctx) ret (sci/binding [sci/out out sci/err err] diff --git a/test/babashka/pods/test_common.clj b/test/babashka/pods/test_common.clj index 7a4d566..760c097 100644 --- a/test/babashka/pods/test_common.clj +++ b/test/babashka/pods/test_common.clj @@ -26,7 +26,8 @@ [[1] [1]] 2 3 - true + true ;; local-date + true ;; roundtrip string array 1] (concat ret (repeat ::nil)))] (if (instance? java.util.regex.Pattern expected)