UNPKG

@solana/codecs-data-structures

Version:

Codecs for various data structures

118 lines 5.79 kB
import { Codec, Decoder, Encoder, ReadonlyUint8Array } from '@solana/codecs-core'; import { GetDecoderTypeFromVariants, GetEncoderTypeFromVariants, GetUnionCodecType, GetUnionDecoderType, GetUnionEncoderType } from './utils'; type SameType<TExpected, TActual> = [TExpected] extends [TActual] ? [TActual] extends [TExpected] ? unknown : never : never; type SameEncoderType<TIfTrue extends Encoder<any>, TIfFalse extends Encoder<any>> = SameType<GetEncoderTypeFromVariants<readonly [TIfTrue]>, GetEncoderTypeFromVariants<readonly [TIfFalse]>>; type SameDecoderType<TIfTrue extends Decoder<any>, TIfFalse extends Decoder<any>> = SameType<GetDecoderTypeFromVariants<readonly [TIfTrue]>, GetDecoderTypeFromVariants<readonly [TIfFalse]>>; type SameCodecType<TIfTrue extends Codec<any>, TIfFalse extends Codec<any>> = SameType<GetEncoderTypeFromVariants<readonly [TIfTrue]>, GetEncoderTypeFromVariants<readonly [TIfFalse]>> & SameType<GetDecoderTypeFromVariants<readonly [TIfTrue]>, GetDecoderTypeFromVariants<readonly [TIfFalse]>>; /** * Returns an encoder that selects between two encoders based on a predicate. * * This encoder uses a boolean predicate function to determine which of two * encoders to use for a given value. If the predicate returns `true`, the * `ifTrue` encoder is used; otherwise, the `ifFalse` encoder is used. * * @typeParam TFrom - The type of the value to encode. * * @param predicate - A function that returns `true` or `false` for a given value. * @param ifTrue - The encoder to use when the predicate returns `true`. * @param ifFalse - The encoder to use when the predicate returns `false`. * @returns An `Encoder` based on the provided encoders. * * @example * Encoding small and large numbers differently. * ```ts * const encoder = getPredicateEncoder( * (n: number) => n < 256, * getU8Encoder(), * getU32Encoder() * ); * * encoder.encode(42); * // 0x2a * // └── Small number encoded as u8 * * encoder.encode(1000); * // 0xe8030000 * // └── Large number encoded as u32 * ``` * * @see {@link getPredicateCodec} */ export declare function getPredicateEncoder<TFrom = any, const TIfTrue extends Encoder<TFrom> = Encoder<TFrom>, const TIfFalse extends Encoder<TFrom> = Encoder<TFrom>>(predicate: (value: TFrom) => boolean, ifTrue: TIfTrue, ifFalse: SameEncoderType<TIfTrue, TIfFalse> & TIfFalse): GetUnionEncoderType<readonly [TIfTrue, TIfFalse]>; /** * Returns a decoder that selects between two decoders based on a predicate. * * This decoder uses a boolean predicate function on the raw bytes to determine * which of two decoders to use. If the predicate returns `true`, the `ifTrue` * decoder is used; otherwise, the `ifFalse` decoder is used. * * @typeParam TTo - The type of the value to decode. * * @param predicate - A function that returns `true` or `false` for a given byte array. * @param ifTrue - The decoder to use when the predicate returns `true`. * @param ifFalse - The decoder to use when the predicate returns `false`. * @returns A `Decoder` based on the provided decoders. * * @example * Decoding small and large numbers based on byte length. * ```ts * const decoder = getPredicateDecoder( * bytes => bytes.length === 1, * getU8Decoder(), * getU32Decoder() * ); * * decoder.decode(new Uint8Array([0x2a])); * // 42 (decoded as u8) * * decoder.decode(new Uint8Array([0xe8, 0x03, 0x00, 0x00])); * // 1000 (decoded as u32) * ``` * * @see {@link getPredicateCodec} */ export declare function getPredicateDecoder<TTo = any, const TIfTrue extends Decoder<TTo> = Decoder<TTo>, const TIfFalse extends Decoder<TTo> = Decoder<TTo>>(predicate: (value: ReadonlyUint8Array) => boolean, ifTrue: TIfTrue, ifFalse: SameDecoderType<TIfTrue, TIfFalse> & TIfFalse): GetUnionDecoderType<readonly [TIfTrue, TIfFalse]>; /** * Returns a codec that selects between two codecs based on predicates. * * This codec uses boolean predicate functions to determine which of two codecs * to use for encoding and decoding. If the encoding predicate returns `true` * for a value, the `ifTrue` codec is used to encode it; otherwise `ifFalse`. * Similarly, if the decoding predicate returns `true` for the bytes, the * `ifTrue` codec is used to decode them. * * @typeParam TFrom - The type of the value to encode. * @typeParam TTo - The type of the value to decode. * * @param encodePredicate - A function that returns `true` or `false` for a given value. * @param decodePredicate - A function that returns `true` or `false` for a given byte array. * @param ifTrue - The codec to use when the respective predicate returns `true`. * @param ifFalse - The codec to use when the respective predicate returns `false`. * @returns A `Codec` based on the provided codecs. * * @example * Encoding and decoding small and large numbers differently. * ```ts * const codec = getPredicateCodec( * (n: number) => n < 256, * bytes => bytes.length === 1, * getU8Codec(), * getU32Codec() * ); * * const smallBytes = codec.encode(42); * // 0x2a (encoded as u8) * * const largeBytes = codec.encode(1000); * // 0xe8030000 (encoded as u32) * * codec.decode(smallBytes); // 42 * codec.decode(largeBytes); // 1000 * ``` * * @see {@link getPredicateEncoder} * @see {@link getPredicateDecoder} */ export declare function getPredicateCodec<TFrom = any, TTo extends TFrom = TFrom, const TIfTrue extends Codec<TFrom, TTo> = Codec<TFrom, TTo>, const TIfFalse extends Codec<TFrom, TTo> = Codec<TFrom, TTo>>(encodePredicate: (value: TFrom) => boolean, decodePredicate: (value: ReadonlyUint8Array) => boolean, ifTrue: TIfTrue, ifFalse: SameCodecType<TIfTrue, TIfFalse> & TIfFalse): GetUnionCodecType<readonly [TIfTrue, TIfFalse]>; export {}; //# sourceMappingURL=predicate.d.ts.map