• @Choice decorator match a field to record object.

    Type Parameters

    • This
    • Value

    Parameters

    • cmp: string | ((targetInstance: This) => any)

      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.

    • match: Record<any, undefined | Primitive<any> | [Primitive<any>, RelationParameters<This>]>

      Match the 'cmp' value to the key of the record for this argument. The value is the relation to read if the value match.

    • Optionalargs: RelationParameters<This>

      The arguments to pass to the matching relation definition (see Primitive.RelationParameters)

    Returns DecoratorType<This, Value>

    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 BinProtocol {
    @While((value: Chunk) => value.type !== 0x03)
    message: Chunk[]
    }

    You can also pass arguments to the relation using comma separeted string. In the following example I pass teh value of the property 'length' and 'type' 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

    @Count('_length')
    @Relation(PrimitiveSymbol.u8)
    data: number[]

    constructor(length: number, type: number) {
    this._length = length
    }
    }

    class Header {
    @Count(4)
    @Relation(PrimitiveSymbol.u8)
    magic: number

    @Relation(PrimitiveSymbol.u32)
    crc: number
    }

    class BinProtocol {
    @Relation(PrimitiveSymbol.u32)
    length: number

    @Relation(PrimitiveSymbol.u8)
    type: number

    @Choice('type', {
    0x01: Header,
    0x02: [Data, 'length, type'],
    0x03: undefined,
    })
    data: number
    }

    Or functions if you want to perform some operation on the data before passing them to the constructor.

    class BinProtocol {
    @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 BinProtocol {
    @Relation(PrimitiveSymbol.u32)
    length: number

    @Relation(PrimitiveSymbol.u8)
    type: number

    @Choice('type', {
    0x01: Header,
    0x02: Data,
    0x03: undefined,
    }, 'length')
    data: number
    }

    To pass to the reader a relation by default use @Choice with the @Else decorator (see Else)

    class Protocol {
    @Relation(PrimitiveSymbol.u8)
    something: number

    @Choice('something', {
    0x01: PrimitiveSymbol.u8
    })
    @Else(PrimitiveSymbol.u16)
    data: number
    }