@solana/codecs-data-structures
Version:
Codecs for various data structures
144 lines • 5.63 kB
TypeScript
import { Codec, Decoder, Encoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder, VariableSizeCodec, VariableSizeDecoder, VariableSizeEncoder } from '@solana/codecs-core';
import { DrainOuterGeneric } from './utils';
/**
* Represents a collection of named fields used in struct codecs.
*
* Each field is defined as a tuple containing:
* - A string key representing the field name.
* - A codec used to encode and decode the field's value.
*
* @typeParam T - The codec type used for each field.
*/
type Fields<T> = readonly (readonly [string, T])[];
type ArrayIndices<T extends readonly unknown[]> = Exclude<Partial<T>['length'], T['length']> & number;
/**
* Infers the TypeScript type for an object that can be encoded using a struct codec.
*
* This type maps the provided field encoders to their corresponding values.
*
* @typeParam TFields - The fields of the struct, each paired with an encoder.
*/
type GetEncoderTypeFromFields<TFields extends Fields<Encoder<any>>> = DrainOuterGeneric<{
[I in ArrayIndices<TFields> as TFields[I][0]]: TFields[I][1] extends Encoder<infer TFrom> ? TFrom : never;
}>;
/**
* Infers the TypeScript type for an object that can be decoded using a struct codec.
*
* This type maps the provided field decoders to their corresponding values.
*
* @typeParam TFields - The fields of the struct, each paired with a decoder.
*/
type GetDecoderTypeFromFields<TFields extends Fields<Decoder<any>>> = DrainOuterGeneric<{
[I in ArrayIndices<TFields> as TFields[I][0]]: TFields[I][1] extends Decoder<infer TTo> ? TTo : never;
}>;
/**
* Returns an encoder for custom objects.
*
* This encoder serializes an object by encoding its fields sequentially,
* using the provided field encoders.
*
* For more details, see {@link getStructCodec}.
*
* @typeParam TFields - The fields of the struct, each paired with an encoder.
*
* @param fields - The name and encoder of each field.
* @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding custom objects.
*
* @example
* Encoding a custom struct.
* ```ts
* const encoder = getStructEncoder([
* ['name', fixCodecSize(getUtf8Encoder(), 5)],
* ['age', getU8Encoder()]
* ]);
*
* const bytes = encoder.encode({ name: 'Alice', age: 42 });
* // 0x416c6963652a
* // | └── Age (42)
* // └── Name ("Alice")
* ```
*
* @see {@link getStructCodec}
*/
export declare function getStructEncoder<const TFields extends Fields<FixedSizeEncoder<any>>>(fields: TFields): FixedSizeEncoder<GetEncoderTypeFromFields<TFields>>;
export declare function getStructEncoder<const TFields extends Fields<Encoder<any>>>(fields: TFields): VariableSizeEncoder<GetEncoderTypeFromFields<TFields>>;
/**
* Returns a decoder for custom objects.
*
* This decoder deserializes an object by decoding its fields sequentially,
* using the provided field decoders.
*
* For more details, see {@link getStructCodec}.
*
* @typeParam TFields - The fields of the struct, each paired with a decoder.
*
* @param fields - The name and decoder of each field.
* @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding custom objects.
*
* @example
* Decoding a custom struct.
* ```ts
* const decoder = getStructDecoder([
* ['name', fixCodecSize(getUtf8Decoder(), 5)],
* ['age', getU8Decoder()]
* ]);
*
* const struct = decoder.decode(new Uint8Array([
* 0x41,0x6c,0x69,0x63,0x65,0x2a
* ]));
* // { name: 'Alice', age: 42 }
* ```
*
* @see {@link getStructCodec}
*/
export declare function getStructDecoder<const TFields extends Fields<FixedSizeDecoder<any>>>(fields: TFields): FixedSizeDecoder<GetDecoderTypeFromFields<TFields>>;
export declare function getStructDecoder<const TFields extends Fields<Decoder<any>>>(fields: TFields): VariableSizeDecoder<GetDecoderTypeFromFields<TFields>>;
/**
* Returns a codec for encoding and decoding custom objects.
*
* This codec serializes objects by encoding and decoding each field sequentially.
*
* @typeParam TFields - The fields of the struct, each paired with a codec.
*
* @param fields - The name and codec of each field.
* @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding custom objects.
*
* @example
* Encoding and decoding a custom struct.
* ```ts
* const codec = getStructCodec([
* ['name', fixCodecSize(getUtf8Codec(), 5)],
* ['age', getU8Codec()]
* ]);
*
* const bytes = codec.encode({ name: 'Alice', age: 42 });
* // 0x416c6963652a
* // | └── Age (42)
* // └── Name ("Alice")
*
* const struct = codec.decode(bytes);
* // { name: 'Alice', age: 42 }
* ```
*
* @remarks
* Separate {@link getStructEncoder} and {@link getStructDecoder} functions are available.
*
* ```ts
* const bytes = getStructEncoder([
* ['name', fixCodecSize(getUtf8Encoder(), 5)],
* ['age', getU8Encoder()]
* ]).encode({ name: 'Alice', age: 42 });
*
* const struct = getStructDecoder([
* ['name', fixCodecSize(getUtf8Decoder(), 5)],
* ['age', getU8Decoder()]
* ]).decode(bytes);
* ```
*
* @see {@link getStructEncoder}
* @see {@link getStructDecoder}
*/
export declare function getStructCodec<const TFields extends Fields<FixedSizeCodec<any>>>(fields: TFields): FixedSizeCodec<GetEncoderTypeFromFields<TFields>, GetDecoderTypeFromFields<TFields> & GetEncoderTypeFromFields<TFields>>;
export declare function getStructCodec<const TFields extends Fields<Codec<any>>>(fields: TFields): VariableSizeCodec<GetEncoderTypeFromFields<TFields>, GetDecoderTypeFromFields<TFields> & GetEncoderTypeFromFields<TFields>>;
export {};
//# sourceMappingURL=struct.d.ts.map