module YAML::Serializable
Overview
The YAML::Serializable
module automatically generates methods for YAML serialization when included.
Example
require "yaml"
class Location
include YAML::Serializable
@[YAML::Field(key: "lat")]
property latitude : Float64
@[YAML::Field(key: "lng")]
property longitude : Float64
end
class House
include YAML::Serializable
property address : String
property location : Location?
end
house = House.from_yaml(%({"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}}))
house.address # => "Crystal Road 1234"
house.location # => #<Location:0x10cd93d80 @latitude=12.3, @longitude=34.5>
house.to_yaml # => "---\naddress: Crystal Road 1234\nlocation:\n lat: 12.3\n lng: 34.5\n"
houses = Array(House).from_yaml("---\n- address: Crystal Road 1234\n location:\n lat: 12.3\n lng: 34.5\n")
houses.size # => 1
houses.to_yaml # => "---\n- address: Crystal Road 1234\n location:\n lat: 12.3\n lng: 34.5\n"
Usage
Including YAML::Serializable
will create #to_yaml
and self.from_yaml
methods on the current class,
and a constructor which takes a YAML::PullParser
. By default, these methods serialize into a yaml
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_yaml and a constructor taking a YAML::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 YAML::Field
can be placed on the instance variable. Annotating property, getter and setter macros is also allowed.
class A
include YAML::Serializable
@[YAML::Field(key: "my_key", emit_null: true)]
getter a : Int32?
end
YAML::Field
properties:
- ignore: if
true
skip this field in seriazation and deserialization (by default false) - key: the value of the key in the yaml object (by default the name of the instance variable)
- converter: specify an alternate type for parsing and generation. The converter must define
from_yaml(YAML::PullParser)
andto_yaml(value, YAML::Builder)
as class methods. Examples of converters areTime::Format
andTime::EpochConverter
forTime
. - presence: if
true
, a@{{key}}_present
instance variable will be generated when the key was present (even if it has anull
value),false
by default - emit_null: if
true
, emits anull
value for nilable property (by default nulls are not emitted)
Deserialization also respects default values of variables:
struct A
include YAML::Serializable
@a : Int32
@b : Float64 = 1.0
end
A.from_yaml("---\na: 1\n") # => A(@a=1, @b=1.0)
Extensions: YAML::Serializable::Strict
and YAML::Serializable::Unmapped
.
If the YAML::Serializable::Strict
module is included, unknown properties in the YAML
document will raise a parse exception. By default the unknown properties
are silently ignored.
If the YAML::Serializable::Unmapped
module is included, unknown properties in the YAML
document will be stored in a Hash(String, YAML::Any)
. On serialization, any keys inside yaml_unmapped
will be serialized appended to the current yaml object.
struct A
include YAML::Serializable
include YAML::Serializable::Unmapped
@a : Int32
end
a = A.from_yaml("---\na: 1\nb: 2\n") # => A(@yaml_unmapped={"b" => 2_i64}, @a=1)
a.to_yaml # => "---\na: 1\nb: 2\n"
Class annotation YAML::Serializable::Options
supported properties:
- emit_nulls: if
true
, emits anull
value for all nilable properties (by default nulls are not emitted)
@[YAML::Serializable::Options(emit_nulls: true)]
class A
include YAML::Serializable
@a : Int32?
end