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

Round-trip fails when write handler returns extension type #23

Open
stuartsierra opened this issue Dec 15, 2015 · 0 comments
Open

Round-trip fails when write handler returns extension type #23

stuartsierra opened this issue Dec 15, 2015 · 0 comments

Comments

@stuartsierra
Copy link

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))))

Tested with these dependencies:

 [com.cognitect/transit-cljs "0.8.232"]
   [com.cognitect/transit-js "0.8.755"]
 [org.clojure/clojure "1.7.0"]
 [org.clojure/clojurescript "1.7.170"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

0 participants