The name of the property of the target instance containing a value or a function receiving the target instance as parameter that return the value to compare to the record param.
A record where keys are compared against the evaluated cmp
value, and
values define the corresponding relations.
Optional
args: RelationParameters<This, Args>The arguments to pass to the matching relation definition (see Primitive.RelationParameters)
The property decorator function.
The simplest way to use the @Choice
decorator is to reference the name
of a property belonging to the target instance to match with the record.
class Chunk {
@Relation(PrimitiveSymbol.u8)
type: number
@Choice('type', {
0x01: PrimitiveSymbol.u8,
0x02: PrimitiveSymbol.u16,
0x03: undefined,
})
data: number
}
class Protocol {
@While((value: Chunk) => value.type !== 0x03)
message: Chunk[]
}
You can also pass arguments to the relation using comma separeted string. In the following example the value of the property 'length' and 'type' is passed to the constructor of 'Data' on creation. Notice that relation you want to pass arguments requires to be defined inside of an array of two member.
class Data {
_length: number
_type: number
@Count('_length')
@Relation(PrimitiveSymbol.u8)
data: number[]
...
constructor(length: number, type: number) {
this._length = length
this._type = type
}
}
class Header {
@Count(4)
@Relation(PrimitiveSymbol.u8)
magic: number
@Relation(PrimitiveSymbol.u32)
crc: number
}
class Protocol {
@Relation(PrimitiveSymbol.u32)
length: number
@Relation(PrimitiveSymbol.u8)
type: number
@Choice('type', {
0x01: Header,
0x02: [Data, 'length, type'],
0x03: undefined,
})
data: Header | Data | undefined
}
An alternative to string reference is to use functions if you need to performs manipulation on the datas.
class Protocol {
@Relation(PrimitiveSymbol.u32)
length: number
@Relation(PrimitiveSymbol.u8)
type: number
@Choice(_ => _.type, {
0x01: Header,
0x02: [Data, (instance: BinProtocol) => [instance.length - 5, instance.type]],
0x03: undefined,
})
data: number
}
You can also define the default arguments you pass to every relations. In the following example the value of the property 'length' will be passed to every relation on creation.
class Protocol {
@Relation(PrimitiveSymbol.u32)
length: number
@Relation(PrimitiveSymbol.u8)
type: number
@Choice('type', {
0x01: Header,
0x02: Data,
0x03: undefined,
}, 'length')
data: number
}
@Choice
decorator match a value to a record of value:primitive.The
@Choice
decorator is just syntactic sugar to the@IfThen
decorator, useful for simple straightforward equality comparaison that doesn't requires any preprocessing.