/** * Module definition of {@link Primitive} property decorators. * * The {@link Primitive} type decorators are used to define the data type of * decorated properties within a binary format definition. They must always * be the first decorator applied to a property (the closest one to the * property). * * ```mermaid * flowchart TB * subgraph s1[For each properties] * direction TB * PreOperation[__Pre__ property reading operations] --> Condition * click PreOperation "/binspector/modules/PrePost.html" "Documentation for 'Pre' type decorators" * Condition[__Condition__ get the definitive subtype to read based on current state] --> s2 * click Condition "/binspector/modules/Condition.html" "Documentation for 'Condtion' type decorators" * subgraph s2[Reading subtype] * Controller[__Controller__ decides when to stop reading the subtype based on a set of arbitrary conditions] --> TypeReading[Read __Relation__ or __Primitive__] * click Controller "/binspector/modules/Controller.html" "Documentation for 'Controller' type decorators" * click TypeReading "/binspector/modules/Primitive.html" "Documentation for 'Primitive' type decorators" * end * TypeReading --> Controller * s2 --> Transform[__Transform__ the value we read into something else] * click Transform "/binspector/modules/Transformer.html" "Documentation for 'Transformer' type decorators" * Transform --> Validate[__Validate__ the final value] * click Validate "/binspector/modules/Validator.html" "Documentation for 'Validator' type decorators" * Validate --> PostOperation[__Post__ property reading operations] * click PostOperation "/binspector/modules/PrePost.html" "Documentation for 'Post' type decorators" * end * PostOperation --> A@{ shape: framed-circle, label: "Stop" } * style TypeReading fill:blue,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 * ``` * * @module Primitive */ import { type PropertyMetaDescriptor, StringFormattedCommaSepRecursiveKeyOf } from './common.ts'; import { PrimitiveSymbol, type InstantiableObject, type DecoratorType, type Context, type DecoratorMetadataObject } from '../types.ts'; /** * `UnknownPropertyType` are primitive type that needs to be defined at * runtime with the help of {@link Condition} decorator. * * @typeParam This The type of the class the decorator is applied to. */ export type UnknownTypeProperty = PropertyMetaDescriptor; /** * `PrimitiveTypeProperty` are primitive type that can be immediately read or * written during the binary reading or writing process. * Those primitive are the following: * - u8: Unsigned 8 bit integer * - u16: Unsigned 16 bit integer * - u32: Unsigned 32 bit integer * - u64: Unsigned 64 bit integer * - i8: Signed 8 bit integer * - i16: Signed 16 bit integer * - i32: Signed 32 bit integer * - i64: Signed 64 bit integer * - float32: Floating point 32 bit number * - float64: Floating point 64 bit number * - char: Character * * @typeParam This The type of the class the decorator is applied to. * * @extends {PropertyMetaDescriptor} */ export interface PrimitiveTypeProperty extends PropertyMetaDescriptor { /** * Property that holds the primitive symbol type. */ primitive: PrimitiveSymbol; } /** * RelationParameters function definition receive the target instance and return an array of parameter to pass to the relation. * * @example * * If we have the following protocol definition. * * ```typescript * class Chunk { * constructor(type, size) { * this._type = type * this._size = size * } * } * class Protocol { * @Relation(PrimitiveSymbol.u8) * type: number * * @Relation(PrimitiveSymbol.u8) * size: number * * @Relation(Chunk, (targetInstance: Protocol) => [targetInstance.type, targetInstance.size]) * data: Chunk * } * ``` * * The `RelationParameters` definition to pass the property `type` and `size` * to the `Chunk` constructor is the following * `(targetInstance: Protocol) => [targetInstance.type, targetInstance.size]` * * @typeParam This The type of the class the decorator is applied to. */ export type RelationParameters = ((targetInstance: This) => any[]) | StringFormattedCommaSepRecursiveKeyOf; /** * `RelationTypeProperty` are primitive type that holds information about * another binary type definition. * * @typeParam This The type of the class the decorator is applied to. * * @extends {PropertyMetaDescriptor} */ export interface RelationTypeProperty extends PropertyMetaDescriptor { /** * Class definition containing a format definition. */ relation: InstantiableObject; /** * Function that retrieve arguments at runtime. */ args: ((targetInstance: This) => any[]) | undefined; } /** * `PropertyType` contains the different types a decorated property can hold. * Either: * - {@link UnknownTypeProperty}: A property that will be defined at runtime. * - {@link PrimitiveTypeProperty}: A property that can be resolved * immediately. * - {@link RelationTypeProperty}: A reference to a nested binary file * definition. * * @typeParam This The type of the class the decorator is applied to. */ export type PropertyType = RelationTypeProperty | PrimitiveTypeProperty | UnknownTypeProperty; /** * `isPrimitiveRelation` check if the property type is a * {@link PrimitiveTypeProperty}. * * @typeParam This The type of the class the decorator is applied to. * * @param {PropertyType} property * @returns {field is PrimitiveTypeProperty} * * @category Type Guards */ export declare function isPrimitiveRelation(property: PropertyType): property is PrimitiveTypeProperty; /** * `isUnknownProperty` check if the property type is an * {@link UnknownTypeProperty}. * * @typeParam This The type of the class the decorator is applied to. * * @param {PropertyType} property * @returns {field is UnknownPropertyType} * * @category Type Guards */ export declare function isUnknownProperty(property: PropertyType): property is UnknownTypeProperty; /** * `isRelation` check if the property type is a {@link RelationTypeProperty}. * * @typeParam This The type of the class the decorator is applied to. * * @param {PropertyType} property * @returns {property is RelationType} * * @category Type Guards */ export declare function isRelation(property: PropertyType): property is RelationTypeProperty; /** * `createPrimitiveTypeProperty` helper to create a * {@link PrimitiveTypeProperty} metadata object. * * @typeParam This The type of the class the decorator is applied to. * * @param {metadata} metadata * @param {keyof T} propertyKey * @param {PrimitiveSymbol} primitive * @returns {PrimitiveTypeProperty} * * @category Advanced Use */ export declare function createPrimitiveTypeProperty(metadata: DecoratorMetadataObject, propertyKey: keyof This, primitive: PrimitiveSymbol): PrimitiveTypeProperty; /** * `createRelationTypeProperty` helper to create a * {@link RelationTypeProperty} metadata object. * * @typeParam This The type of the class the decorator is applied to. * @typeParam Target The type of the relation * * @param {metadata} metadata * @param {keyof This} propertyKey * @param {InstantiableObject} relation * @param {RelationParameters} args * @returns {RelationTypeProperty} * * @category Advanced Use */ export declare function createRelationTypeProperty(metadata: DecoratorMetadataObject, propertyKey: keyof This, relation: InstantiableObject, args?: RelationParameters): RelationTypeProperty; /** * @overload * @returns {DecoratorType} The property decorator function. */ /** * @overload * @param {PrimitiveSymbol} relation Primitive type of the property. * @returns {DecoratorType} The property decorator function. */ /** * @overload * @param {InstantiableObject} relation Class definition reference of the * nested type definition. * @param {RelationParameters} [args] Optional arguments passed to the * nested type definition. * @returns {DecoratorType} The property decorator function. */ /** * `@Relation` property decorator defines the type of the decorated * property. This can be either: * - A {@link PrimitiveSymbol} type, that refers to a type definition that * will be processed immediately. * - A {@link RelationTypeProperty} type, that refers to a nested type * definition * * @example * * The most basic usage of the `@Relation` is to define the primitive type of * the decorated property. * In the following example a basic format definition is written that defines * the `data` property as an _unsigned 8 bit integer_. * * ```typescript * class Protocol { * @Relation(PrimitiveSymbol.u8) * data: number * } * ``` * * The `@Relation` decorator can also be used to refer to a nested structure. * In the following example the `Protocol` format definition refers to the * `Coord` definition with the `@Relation` decorator. * This will result in a nested object accessible through the property * `data`. * * ```typescript * class Coord { * @Relation(PrimitiveSymbol.i16) * x: number * * @Relation(PrimitiveSymbol.i16) * y: number * } * * class Protocol { * @Relation(Coord) * data: number * } * ``` * * It's also possible to use `@Relation` decorator to pass arguments to the * nested object relation. * * ```typescript * class SubProtocol { * _count: number * * constructor(count: number) { * this._count = count * } * } * * class Protocol { * @Relation(PrimitiveType.u8) * count: number * * // Can refer to the argument just with a string * // to pass multiple arguments you can use comma-separeted references. * @Relation(SubProtocol, 'count') * sub: SubProtocol * * // Using function is also possible, the return type needs to be an array. * @Relation(SubProtocol, (_) => [_.count]) * sub_: SubProtocol * } * ``` * * @remarks * * Even thought it's possible to use the `@Relation()` decorator without * parameters you shouldn't do it yourself. This will be automatically done * with the help of {@link Condition} decorators. * * @typeParam This The type of the class the decorator is applied to. * @typeParam Target The type of the relation * @typeParam Value The type of the decorated property. * * @param {InstantiableObject | PrimitiveSymbol} [relation] Defines the * property type as either a primitive, a nested type definition, or null in * case of an unknown property. * @param {RelationParameters} [args] Optional arguments passed to the * nested type definition. * @returns {DecoratorType} The property decorator function. * * @throws {@link RelationAlreadyDefinedError} if a relation metadata is found. * * @category Decorators */ export declare function Relation(relation?: InstantiableObject | PrimitiveSymbol, args?: RelationParameters): DecoratorType; /** * `@Uint8` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.u8)`. * * Using this decorator specifies that the decorated property should be * interpreted as an unsigned 8 bits integer. * * @example * * ```typescript * class Protocol { * @Uint8 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Uint8(_1: undefined, _2: Context): void; /** * `@Uint16` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.u16)`. * * Using this decorator specifies that the decorated should be interpreted as a * unsigned 16 bits integer. * * @example * * ```typescript * class Protocol { * @Uint16 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Uint16(_1: undefined, _2: Context): void; /** * `@Uint24` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.u24)`. * * Using this decorator specifies that the decorated property should be * interpreted as an unsigned 24 bits integer. * * @example * * ```typescript * class Protocol { * @Uint24 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Uint24(_: undefined, context: Context): void; /** * `@Uint32` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.u32)`. * * Using this decorator specifies that the decorated property should be * interpreted as an unsigned 32 bits integer. * * @example * * ```typescript * class Protocol { * @Uint32 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Uint32(_1: undefined, _2: Context): void; /** * `@Uint64` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.u64)`. * * Using this decorator specifies that the decorated property should be * interpreted as an unsigned 64 bits integer. * * @example * * ```typescript * class Protocol { * @Uint64 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Uint64(_1: undefined, _2: Context): void; /** * `@Int8` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.i8)`. * * Using this decorator specifies that the decorated property should be * interpreted as a signed 8 bits integer. * * @example * * ```typescript * class Protocol { * @Int8 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Int8(_1: undefined, _2: Context): void; /** * `@Int16` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.i16)`. * * Using this decorator specifies that the decorated property should be * interpreted as a signed 16 bits integer. * * @example * * ```typescript * class Protocol { * @Int16 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Int16(_: undefined, context: Context): void; /** * `@Int24` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.i24)`. * * Using this decorator specifies that the decorated property should be * interpreted as a signed 24 bits integer. * * @example * * ```typescript * class Protocol { * @Int24 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Int24(_: undefined, context: Context): void; /** * `@Int32` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.i32)`. * * Using this decorator specifies that the decorated property should be * interpreted as a signed 32 bits integer. * * @example * * ```typescript * class Protocol { * @Int32 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Int32(_: undefined, context: Context): void; /** * `@Int64` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.i64)`. * * Using this decorator specifies that the decorated property should be * interpreted as a signed 64 bits integer. * * @example * * ```typescript * class Protocol { * @Int64 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Int64(_: undefined, context: Context): void; /** * `@Float32` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.float32)`. * * Using this decorator specifies that the decorated property should be * interpreted as a signed 32 bits floating point number. * * @example * * ```typescript * class Protocol { * @Float32 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Float32(_: undefined, context: Context): void; /** * `@Float64` decorator is syntactic sugar for `@Relation(PrimitiveSymbol.float64)`. * * Using this decorator specifies that the decorated property should be * interpreted as a signed 64 bits floating point number. * * @example * * ```typescript * class Protocol { * @Float64 * data: number * } * ``` * * @see {@link Relation} * * @typeParam This The type of the class the decorator is applied to. * @typeParam Value The type of the decorated property. * * @category Decorators */ export declare function Float64(_: undefined, context: Context): void;