UNPKG

@metaplex-foundation/umi-serializers

Version:

A comprehensive set of serializers for the Umi framework

72 lines (66 loc) 2.75 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var umiSerializersCore = require('@metaplex-foundation/umi-serializers-core'); var umiSerializersNumbers = require('@metaplex-foundation/umi-serializers-numbers'); var errors = require('./errors.cjs'); /** * Defines a scalar enum as a type from its constructor. * * @example * ```ts * enum Direction { Left, Right }; * type DirectionType = ScalarEnum<Direction>; * ``` * * @category Serializers */ /** * Creates a scalar enum serializer. * * @param constructor - The constructor of the scalar enum. * @param options - A set of options for the serializer. * @category Serializers */ function scalarEnum(constructor, options = {}) { const prefix = options.size ?? umiSerializersNumbers.u8(); const enumKeys = Object.keys(constructor); const enumValues = Object.values(constructor); const isNumericEnum = enumValues.some(v => typeof v === 'number'); const valueDescriptions = enumValues.filter(v => typeof v === 'string').join(', '); const minRange = 0; const maxRange = isNumericEnum ? enumValues.length / 2 - 1 : enumValues.length - 1; const stringValues = isNumericEnum ? [...enumKeys] : [...new Set([...enumKeys, ...enumValues])]; function assertValidVariant(variant) { const isInvalidNumber = typeof variant === 'number' && (variant < minRange || variant > maxRange); const isInvalidString = typeof variant === 'string' && !stringValues.includes(variant); if (isInvalidNumber || isInvalidString) { throw new errors.InvalidScalarEnumVariantError(variant, stringValues, minRange, maxRange); } } return { description: options.description ?? `enum(${valueDescriptions}; ${prefix.description})`, fixedSize: prefix.fixedSize, maxSize: prefix.maxSize, serialize: value => { assertValidVariant(value); if (typeof value === 'number') return prefix.serialize(value); const valueIndex = enumValues.indexOf(value); if (valueIndex >= 0) return prefix.serialize(valueIndex); return prefix.serialize(enumKeys.indexOf(value)); }, deserialize: (bytes, offset = 0) => { if (bytes.slice(offset).length === 0) { throw new umiSerializersCore.DeserializingEmptyBufferError('enum'); } const [value, newOffset] = prefix.deserialize(bytes, offset); const valueAsNumber = Number(value); offset = newOffset; if (valueAsNumber < minRange || valueAsNumber > maxRange) { throw new errors.EnumDiscriminatorOutOfRangeError(valueAsNumber, minRange, maxRange); } return [isNumericEnum ? valueAsNumber : enumValues[valueAsNumber], offset]; } }; } exports.scalarEnum = scalarEnum; //# sourceMappingURL=scalarEnum.cjs.map