-
Notifications
You must be signed in to change notification settings - Fork 1
Encoding Unions
This tutorial show how to encode values that can be of variable type in the TIER format. The mappings we will be focusing on in this tutorial is standard.union and standard.optional which are located in the tier.standard module.
In TIER a union is a set of different types, where a value encoded as a union will be a value that is one of these types. A union mapping is an aggregate mapping that uses one or more sub mappings. The sub mappings can be any sort of mapping including other union mappings, however one rarely wants to use unions as sub mappings to other unions. In general unions serve two different purposes, the first purpose is to allow for making encoding of some values optional, and the second use case is to create semi dynamic mappings where a few different types are possible. (It is possible to represent most kinds of lua values as a union mapping. In the tutorial Creating Generic Lua Value Mappings we will see an example of just that.)
The standard union mapping is based on the lua type function. A union is constructed using a table that maps from a string name of a type to a mapping for that type. There exists a special case version of the standard union mapping. The optional mapping. This is simply a mapping that maps from a lua value or no value (void). This is useful to indicate values in a TIER mapping that can be optional.
Creation
--Creates a union mapping
-- type_mappings is a table with string keys and
-- mapping values.
standard.union(type_mappings)
--Creates an optional mapping.
--mapping is a mapping of the type that can be optional
standard.optional(mapping)Usage Examples
local tier = require"tier"
local primitive = tier.primitive
local standard = tier.standard
--Creates a mapping that can map between string or number
--values and their TIER tier.
local string_or_int_mapping = standard.union
{
{ type = "number", mapping = primitive.int32 },
{ type = "string", mapping = primitive.string }
}
local item_mapping = standard.tuple
{
{ key = "item_number", mapping = primitive.int32 },
{ key = "readable_name", mapping = standard.optional(primitive.string) }
}
local with_name = { item_number = 13, redable_name = "XRay-goggles" }
local without_name = { item_number = 14 }
local output = io.open("Unions.dat", "wb")
--Encodes a integer value
tier.encode(output, 123, string_or_int_mapping)
--Encodes a string value
tier.encode(output, "Hello", string_or_int_mapping)
--Encodes a value with the optional value present.
tier.encode(output, with_name, item_mapping)
--Encodes a value without the optional value
tier.encode(output, without_name, item_mapping)
output:close()
local input = io.open("Unions.dat", "rb")
local a_string = tier.decode(input, string_or_int_mapping)
local a_int = tier.decode(input, string_or_int_mapping)
local item_with_name = tier.decode(input, item_mapping)
local item_without_name = tier.decode(input, item_mapping)
input:close()This marks the end of this tutorial. In the next tutorial Encoding References we will see how we can encode values as references.