It appears that when a write handler returns an object which is not a Transit ground type, the corresponding read handler gets called with a decoder.Tag value instead of the fully-decoded value.
This only applies in :json mode, not :json-verbose.
Sample ClojureScript code:
(ns example
(:require [cognitect.transit :as transit]))
(defrecord VectorBox [value])
(defrecord ListBox [value])
;; This Transit write handler returns a Vector, which is a Transit
;; ground type.
(deftype VectorBoxWriteHandler []
Object
(tag [_ box] "vectorbox")
(rep [_ box] (vec (:value box)))
(stringRep [_ box] nil))
;; This Transit write handler returns a List, which is an extension
;; type in Transit, not a ground type.
(deftype ListBoxWriteHandler []
Object
(tag [_ box] "listbox")
(rep [_ box] (list* (:value box)))
(stringRep [_ box] nil))
(def my-write-handlers
{VectorBox (VectorBoxWriteHandler.)
ListBox (ListBoxWriteHandler.)})
(def my-read-handlers
{"vectorbox" (fn [rep] (->VectorBox (vec rep)))
"listbox" (fn [rep] (->ListBox (vec rep)))})
(defn round-trip
"Returns the result of writing value with Transit and then reading
it back. transit-type is either :json or :json-verbose"
[value transit-type]
{:pre [(contains? #{:json :json-verbose} transit-type)]}
(transit/read
(transit/reader transit-type {:handlers my-read-handlers})
(transit/write
(transit/writer transit-type {:handlers my-write-handlers})
value)))
(def test-value {:listbox (->ListBox [1 2 3])
:vectorbox (->VectorBox [1 2 3])})
(defn test-round-trip-verbose
"Asserts that we can successfully round-trip a value through transit
using :json-verbose encoding."
[]
(assert (= test-value (round-trip test-value :json-verbose))))
(defn test-round-trip-json
"Asserts that we can successfully round-trip a value through transit
using :json encoding. This test fails."
[]
(assert (= test-value (round-trip test-value :json))))
It appears that when a write handler returns an object which is not a Transit ground type, the corresponding read handler gets called with a
decoder.Tag
value instead of the fully-decoded value.This only applies in
:json
mode, not:json-verbose
.Sample ClojureScript code:
Tested with these dependencies: