module MessagePack::Serializable
Overview
The MessagePack::Serializable module automatically generates methods for MessagePack serialization when included.
Example
require "msgpack"
class Location
include MessagePack::Serializable
@[MessagePack::Field(key: "lat")]
property latitude : Float64
@[MessagePack::Field(key: "lng")]
property longitude : Float64
end
class House
include MessagePack::Serializable
property address : String
property location : Location?
end
house = House.from_msgpack({address: "Crystal Road 1234", location: {"lat": 12.3, "lng": 34.5}}.to_msgpack)
house.address # => "Crystal Road 1234"
house.location # => #<Location:0x10cd93d80 @latitude=12.3, @longitude=34.5>
house.to_msgpack # => Bytes[130, 167, 97, 100, 100, 114, 101, 115, ...
houses = Array(House).from_msgpack([{address: "Crystal Road 1234", location: {"lat": 12.3, "lng": 34.5}}].to_msgpack)
houses.size # => 1
houses.to_msgpack # => Bytes[145, 130, 167, 97, 100, 100, 114, 101, ...
Usage
Including MessagePack::Serializable will create #to_msgpack and self.from_msgpack methods on the current class,
and a constructor which takes a MessagePack::PullParser. By default, these methods serialize into a msgpack
object containing the value of every instance variable, the keys being the instance variable name.
Most primitives and collections supported as instance variable values (string, integer, array, hash, etc.),
along with objects which define to_msgpack and a constructor taking a MessagePack::PullParser.
Union types are also supported, including unions with nil. If multiple types in a union parse correctly,
it is undefined which one will be chosen.
To change how individual instance variables are parsed and serialized, the annotation MessagePack::Field
can be placed on the instance variable. Annotating property, getter and setter macros is also allowed.
class A
include MessagePack::Serializable
@[MessagePack::Field(key: "my_key", emit_null: true)]
getter a : Int32?
end
MessagePack::Field properties:
- ignore: if
trueskip this field in seriazation and deserialization (by default false) - key: the value of the key in the msgpack object (by default the name of the instance variable)
- root: assume the value is inside a MessagePack object with a given key (see
Object.from_msgpack(string_or_io, root)) - converter: specify an alternate type for parsing and generation. The converter must define
from_msgpack(MessagePack::PullParser)andto_msgpack(value, MessagePack::Builder)as class methods. Examples of converters areTime::FormatandTime::EpochConverterforTime. - presense: if
true, a@{{key}}_presentinstance variable will be generated when the key was present (even if it has anullvalue),falseby default - emit_null: if
true, emits anullvalue for nilable property (by default nulls are not emitted)
Deserialization also respects default values of variables:
struct A
include MessagePack::Serializable
@a : Int32
@b : Float64 = 1.0
end
A.from_msgpack({a: 1}.to_msgpack) # => A(@a=1, @b=1.0)
Extensions: MessagePack::Serializable::Strict and MessagePack::Serializable::Unmapped.
If the MessagePack::Serializable::Strict module is included, unknown properties in the MessagePack
document will raise a parse exception. By default the unknown properties
are silently ignored.
If the MessagePack::Serializable::Unmapped module is included, unknown properties in the MessagePack
document will be stored in a Hash(String, MessagePack::Any). On serialization, any keys inside msgpack_unmapped
will be serialized appended to the current msgpack object.
struct A
include MessagePack::Serializable
include MessagePack::Serializable::Unmapped
@a : Int32
end
a = A.from_msgpack({a: 1, b: 2}.to_msgpack) # => A(@msgpack_unmapped={"b" => 2_i64}, @a=1)
Hash(String, MessagePack::Type).from_msgpack(a.to_msgpack) # => {"a" => 1_u8, "b" => 2_u8}
Class annotation MessagePack::Serializable::Options
supported properties:
- emit_nulls: if
true, emits anullvalue for all nilable properties (by default nulls are not emitted)
@[MessagePack::Serializable::Options(emit_nulls: true)]
class A
include MessagePack::Serializable
@a : Int32?
end