# OneOf
OneOf allows you to serialize and deserialize a value of a union type, that is,
a value that can be of one of the multiple types. sd.oneOf
takes
a definition object whose keys are names of possible types of a value,
and values are sd.Serdes<T>
which are used to encode and decode
values of that type.
sd.oneOf
maps each type to unique integer and writes it at the
beginning of the payload to differentiate between types. It's first
parameter is headSd
, which is sd.Serdes<number>
used to encode the
unique integer
The following sd.oneOf
call:
const oneOf = sd.oneOf(sd.uint8, {
a: sd.uint8,
b: sd.array(sd.uint8, sd.uint8),
foo: sd.struct({
x: sd.float64,
y: sd.float64
})
});
will create sd.Serdes<U>
, where U
is a union type:
type U = {
type: "a";
value: number;
} | {
type: "b";
value: number[];
} | {
type: "foo";
value: {
x: number;
y: number;
};
};
And types "a", "b" and "foo" will be mapped to unique integer encoded
by sd.uint8
# Usage
const oneOf = sd.oneOf(sd.uint8, {
a: sd.uint8,
b: sd.array(sd.uint8, sd.uint8),
foo: sd.struct({
x: sd.float64,
y: sd.float64
})
});
const { toBytes, fromBytes } = sd.use(oneOf);
const obj: sd.GetType<typeof oneOf> = {
type: "foo",
value: {
x: 42,
y: 42
}
};
const bytes = toBytes(obj);
const result = fromBytes(bytes);
switch (result.type) {
case "a":
console.log(typeof result.value); //number
break;
case "b":
console.log(result.value.join(", "));
break;
case "foo":
console.log(`x = ${result.value.x}, y = ${result.value.y}`);
break;
}
# Specifications
sd.oneOf
first serializes integer which is used to differentiate
different types, and then serializes a value of that type using the
corresponding sd.Serdes<T>
in the definition object
Values of the integer are mapped to the properties of the definition
object (that is, possible types of a value) starting from 0
, in order in which
the properties appear on the object. So, in the example above values are mapped
to the properties (types) like this:
0 -> "a"
1 -> "b"
2 -> "foo"
The payload will be in the one of the following forms:
[headSd 0][a value (uint8)]
[headSd 1][b number of items (uint8)][...b items (uint8)]
[headSd 2][c.x (float64)][c.y (float64)]