-
Notifications
You must be signed in to change notification settings - Fork 12
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
Conflict between Record and IPersistentMap #26
Comments
For now, I managed to hack my way around the issue by overriding the implementation of (require '[msgpack.core :as msgpack])
(require '[msgpack.macros :refer [extend-msgpack]])
(require msgpack.clojure-extensions)
(defonce record-type-map (atom {}))
(defmacro extend-msgpack-record [cl type map->cl]
`(let [type# ~type]
(swap! record-type-map assoc (.getName ~cl) type#)
(defmethod msgpack/refine-ext type# [{:keys [~'data]}]
(~map->cl (msgpack/unpack ~'data)))))
(defn- pack-coll
[coll ^DataOutput s opts]
(doseq [item coll] (msgpack/packable-pack item s opts)))
(extend-protocol msgpack/Packable
IPersistentMap
(packable-pack [map ^DataOutput s opts]
(if-let [t (@record-type-map (.getName (class map)))]
(msgpack/packable-pack (msgpack/->Ext t (msgpack/pack (into {} map))) s opts)
(msgpack/cond-let [len (count map)
pairs (interleave (keys map) (vals map))]
(<= len 0xf)
(do (.writeByte s (bit-or 2r10000000 len)) (pack-coll pairs s opts))
(<= len 0xffff)
(do (.writeByte s 0xde) (.writeShort s len) (pack-coll pairs s opts))
(<= len 0xffffffff)
(do (.writeByte s 0xdf) (.writeInt s len) (pack-coll pairs s opts)))))) And then I can define an extension for a record by doing this: (extend-msgpack-record Foo 21 map->Foo) Since Records are a feature of the language, it would be nice if this use-case was supported by the library itself. With this workaround, I have to be very careful not to accidentally reload the |
Thanks for the bug report. I'll have a look sometime this week. |
It also puzzled me how can you I tried to implement generic record packing/unpacking in #27 , with some success on the CLJS side. I got it working, but it was relying on record's FQN, however in CLJS advanced compilation, the names are mangled. However, I believe that you can easily do this in CLJ, on JVM. What I did was that I replaced (in |
I have a record like this:
and I would like to make it serializable, like this:
However, this causes undefined behavior because a
Foo
record is also anIPersistentMap
. Sometimes the record gets serialized correctly, sometimes it gets serialized as a simple map.What's the best solution to this problem?
The text was updated successfully, but these errors were encountered: