clojure-msgpack is a lightweight and simple library for converting between native Clojure data structures and MessagePack byte formats. clojure-msgpack only depends on Clojure itself; it has no third-party dependencies.
Get it from clojars: https://clojars.org/clojure-msgpack
pack: Serialize object as a sequence of java.lang.Bytes.unpackDeserialize bytes as a Clojure object.
(require '[msgpack.core :as msg]) (require 'msgpack.clojure-extensions) (msg/pack {:compact true :schema 0}) ; => #<byte[] [B@60280b2e> (msg/unpack (msg/pack {:compact true :schema 0})) ; => {:schema 0, :compact true}unpack-stream: Takes a java.io.DataInput as an argument. Usually you wrap this around an InputStreampack-stream: Takes a java.io.DataOutput as an argument. Usually you wrap this around an OutputStream
(use 'clojure.java.io) (import '(java.io.DataOutputStream) '(java.io.DataInputStream)) (with-open [o (output-stream "test.dat")] (let [data-output (java.io.DataOutputStream. o)] (msg/pack-stream {:compact true :schema 0} data-output))) (with-open [i (input-stream "test.dat")] (let [data-input (java.io.DataInputStream. i)] (msg/unpack-stream data-input))) ; => {:schema 0, :compact true}| Clojure | MessagePack |
|---|---|
| nil | Nil |
| java.lang.Boolean | Boolean |
| java.lang.Byte | Integer |
| java.lang.Short | Integer |
| java.lang.Integer | Integer |
| java.lang.Long | Integer |
| java.lang.BigInteger | Integer |
| clojure.lang.BigInt | Integer |
| java.lang.Float | Float |
| java.lang.Double | Float |
| java.math.BigDecimal | Float |
| java.lang.String | String |
| clojure.lang.Sequential | Array |
| clojure.lang.IPersistentMap | Map |
| msgpack.core.Ext | Extended |
Serializing a value of unrecognized type will fail with IllegalArgumentException. See Application types if you want to register your own types.
Some native Clojure types don't have an obvious MessagePack counterpart. We can serialize them as Extended types. To enable automatic conversion of these types, load the clojure-extensions library.
| Clojure | MessagePack |
|---|---|
| clojure.lang.Keyword | Extended (type = 3) |
| clojure.lang.Symbol | Extended (type = 4) |
| java.lang.Character | Extended (type = 5) |
| clojure.lang.Ratio | Extended (type = 6) |
| clojure.lang.IPersistentSet | Extended (type = 7) |
With msgpack.clojure-extensions:
(require 'msgpack.clojure-extensions) (msg/pack :hello) ; => #<byte[] [B@a8c55bf>Without msgpack.clojure-extensions:
(msg/pack :hello) ; => IllegalArgumentException No implementation of method: :pack-stream of ; protocol: #'msgpack.core/Packable found for class: clojure.lang.Keyword ; clojure.core/-cache-protocol-fn (core _deftype.clj:544)You can also define your own Extended types with extend-msgpack.
(require '[msgpack.macros :refer [extend-msgpack]]) (defrecord Person [name]) (extend-msgpack Person 100 [p] (.getBytes (:name p)) [bytes] (->Person (String. bytes))) (msg/unpack (msg/pack [(->Person "bob") 5 "test"])) ; => (#user.Person{:name "bob"} 5 "test")clojure-msgpack is MIT licensed. See the included LICENSE file for more details.