cognitect / transit-cljs

Transit for ClojureScript
http://transit-format.org
Apache License 2.0
323 stars 20 forks source link

Add support for sorted map entries #50

Closed mfikes closed 2 years ago

mfikes commented 5 years ago

transit-clj supports writing map entries (as 2-element vectors). Here is an example:

$ clj -Sdeps '{:deps {com.cognitect/transit-clj {:mvn/version "0.8.313"}}}'
Clojure 1.10.1
user=> (require '[cognitect.transit :as transit])
nil
user=> (import [java.io ByteArrayInputStream ByteArrayOutputStream])
java.io.ByteArrayOutputStream
user=> (def out (ByteArrayOutputStream. 4096))
#'user/out
user=> (def writer (transit/writer out :json))
#'user/writer
user=> (transit/write writer (first (sorted-map :a 1)))
nil
user=> (.toString out)
"[\"~:a\",1]"

But, transit-cljs doesn't support this. Here is an example, illustrating attempting to write a cljs.core/BlackNode:

$ clj -Sdeps '{:deps {com.cognitect/transit-cljs {:mvn/version "0.8.256"} org.clojure/clojurescript {:mvn/version "1.10.520"}}}' -m cljs.main
ClojureScript 1.10.520
cljs.user=> (require '[cognitect.transit :as t])
nil
(defn roundtrip [x]
  (let [w (t/writer :json)
        r (t/reader :json)]
    (t/read r (t/write w x))))
#'cljs.user/roundtrip
cljs.user=> (roundtrip (first (sorted-map :a 1)))
Execution error (Error) at (<cljs repl>:1).
Cannot write

Additionally, note that support for seqs on sorted maps ostensibly exists, but any such seq would convey cljs.core/BlackNode and/or cljs.core/RedNode entries. Adding handlers for these two types fixes the direct round-tripping of them as described above, but also enables round-tripping of seqs on sorted maps (which works in Clojure).