module SBAN::Serializable

Overview

The SBAN::Serializable module automatically generates methods for SBAN serialization when included.

Example

require "sban"

class Location
  include SBAN::Serializable

  @[SBAN::Field(key: "lat")]
  property latitude : Float64

  @[SBAN::Field(key: "lng")]
  property longitude : Float64
end

class House
  include SBAN::Serializable

  property address : String
  property location : Location?
end

house = House.from_sban({"address" => "Crystal Road 1234", "location" => {"lat" => 12.3, "lng" => 34.5}}.to_sban)
house.address  # => "Crystal Road 1234"
house.location # => #<Location:0x10cd93d80 @latitude=12.3, @longitude=34.5>
house.to_sban  # => Bytes[...]

houses = Array(House).from_sban([{"address" => "Crystal Road 1234", "location" => {"lat" => 12.3, "lng" => 34.5}}].to_sban)
houses.size    # => 1
houses.to_sban # Bytes[...]

Usage

Including SBAN::Serializable will create #to_sban and self.from_sban methods on the current class, and a constructor which takes a SBAN::Decoder. By default, these methods serialize into a sban 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_sban and a constructor taking a SBAN::Decoder. 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 SBAN::Field can be placed on the instance variable. Annotating property, getter and setter macros is also allowed.

require "sban"

class A
  include SBAN::Serializable

  @[SBAN::Field(key: "my_key")]
  getter a : Int32?
end

SBAN::Field properties:

Deserialization also respects default values of variables:

require "sban"

struct A
  include SBAN::Serializable
  @a : Int32
  @b : Float64 = 1.0
end

A.from_sban({"a" => 1}.to_sban) # => A(@a=1, @b=1.0)

Extensions: SBAN::Serializable::Unmapped.

If the SBAN::Serializable::Unmapped module is included, unknown properties in the SBAN document will be stored in a Hash(String, SBAN::Type). On serialization, any keys inside sban_unmapped will be serialized and appended to the current json object.

require "sban"

struct A
  include JSON::Serializable
  include JSON::Serializable::Unmapped
  @a : Int32
end

a = A.from_json(%({"a":1,"b":2})) # => A(@json_unmapped={"b" => 2_i64}, @a=1)
a.to_json                         # => {"a":1,"b":2}

Class annotation SBAN::Serializable::Options

supported properties:

require "json"

@[SBAN::Serializable::Options(emit_nulls: true)]
class A
  include JSON::Serializable
  @a : Int32?
end

Discriminator field

A very common JSON serialization strategy for handling different objects under a same hierarchy is to use a discriminator field. For example in GeoJSON each object has a "type" field, and the rest of the fields, and their meaning, depend on its value.

You can use JSON::Serializable.use_json_discriminator for this use case.

Direct including types

Defined in:

sban/serializable.cr

Constructors

Instance Method Summary

Constructor Detail

def self.new(*, __decoder_for_sban_serializable decoder : SBAN::Decoder) #

[View source]

Instance Method Detail

def to_sban(sban : SBAN::Encoder) #

[View source]