import { Codec, Decoder, Encoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder, VariableSizeCodec, VariableSizeDecoder, VariableSizeEncoder } from '@solana/codecs-core';
import { NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';
import { ArrayLikeCodecSize } from './array';
/**
 * Defines the configuration options for map codecs.
 *
 * The `size` option determines how the number of entries in the map is stored.
 * It can be:
 * - A {@link NumberCodec} to prefix the map with its size.
 * - A fixed number of entries.
 * - `'remainder'`, which infers the number of entries based on the remaining bytes.
 *   This option is only available for fixed-size keys and values.
 *
 * @typeParam TPrefix - A number codec, encoder, or decoder used for the size prefix.
 */
export type MapCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {
    /**
     * The size of the map.
     * @defaultValue u32 prefix.
     */
    size?: ArrayLikeCodecSize<TPrefix>;
};
/**
 * Returns an encoder for maps.
 *
 * This encoder serializes maps where the keys and values are encoded
 * using the provided key and value encoders. The number of entries
 * is determined by the `size` configuration.
 *
 * For more details, see {@link getMapCodec}.
 *
 * @typeParam TFromKey - The type of the keys before encoding.
 * @typeParam TFromValue - The type of the values before encoding.
 *
 * @param key - The encoder for the map's keys.
 * @param value - The encoder for the map's values.
 * @param config - Configuration options for encoding the map.
 * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding maps.
 *
 * @example
 * Encoding a map with a `u32` size prefix.
 * ```ts
 * const encoder = getMapEncoder(fixCodecSize(getUtf8Encoder(), 5), getU8Encoder());
 * const bytes = encoder.encode(new Map([['alice', 42], ['bob', 5]]));
 * // 0x02000000616c6963652a626f62000005
 * //   |       |         | |         └── Value (5)
 * //   |       |         | └── Key ("bob", 5 bytes fixed, null-padded)
 * //   |       |         └── Value (42)
 * //   |       └── Key ("alice", 5 bytes fixed)
 * //   └── 4-byte prefix (2 entries)
 * ```
 *
 * @see {@link getMapCodec}
 */
export declare function getMapEncoder<TFromKey, TFromValue>(key: Encoder<TFromKey>, value: Encoder<TFromValue>, config: MapCodecConfig<NumberEncoder> & {
    size: 0;
}): FixedSizeEncoder<Map<TFromKey, TFromValue>, 0>;
export declare function getMapEncoder<TFromKey, TFromValue>(key: FixedSizeEncoder<TFromKey>, value: FixedSizeEncoder<TFromValue>, config: MapCodecConfig<NumberEncoder> & {
    size: number;
}): FixedSizeEncoder<Map<TFromKey, TFromValue>>;
export declare function getMapEncoder<TFromKey, TFromValue>(key: Encoder<TFromKey>, value: Encoder<TFromValue>, config?: MapCodecConfig<NumberEncoder>): VariableSizeEncoder<Map<TFromKey, TFromValue>>;
/**
 * Returns a decoder for maps.
 *
 * This decoder deserializes maps where the keys and values are decoded
 * using the provided key and value decoders. The number of entries
 * is determined by the `size` configuration.
 *
 * For more details, see {@link getMapCodec}.
 *
 * @typeParam TToKey - The type of the keys after decoding.
 * @typeParam TToValue - The type of the values after decoding.
 *
 * @param key - The decoder for the map's keys.
 * @param value - The decoder for the map's values.
 * @param config - Configuration options for decoding the map.
 * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding maps.
 *
 * @example
 * Decoding a map with a `u32` size prefix.
 * ```ts
 * const decoder = getMapDecoder(fixCodecSize(getUtf8Decoder(), 5), getU8Decoder());
 * const map = decoder.decode(new Uint8Array([
 *   0x02,0x00,0x00,0x00,0x61,0x6c,0x69,0x63,0x65,0x2a,0x62,0x6f,0x62,0x00,0x00,0x05
 * ]));
 * // new Map([['alice', 42], ['bob', 5]])
 * ```
 *
 * @see {@link getMapCodec}
 */
export declare function getMapDecoder<TToKey, TToValue>(key: Decoder<TToKey>, value: Decoder<TToValue>, config: MapCodecConfig<NumberDecoder> & {
    size: 0;
}): FixedSizeDecoder<Map<TToKey, TToValue>, 0>;
export declare function getMapDecoder<TToKey, TToValue>(key: FixedSizeDecoder<TToKey>, value: FixedSizeDecoder<TToValue>, config: MapCodecConfig<NumberDecoder> & {
    size: number;
}): FixedSizeDecoder<Map<TToKey, TToValue>>;
export declare function getMapDecoder<TToKey, TToValue>(key: Decoder<TToKey>, value: Decoder<TToValue>, config?: MapCodecConfig<NumberDecoder>): VariableSizeDecoder<Map<TToKey, TToValue>>;
/**
 * Returns a codec for encoding and decoding maps.
 *
 * This codec serializes maps where the key/value pairs are encoded
 * and decoded one after another using the provided key and value codecs.
 * The number of entries is determined by the `size` configuration and
 * defaults to a `u32` size prefix.
 *
 * @typeParam TFromKey - The type of the keys before encoding.
 * @typeParam TFromValue - The type of the values before encoding.
 * @typeParam TToKey - The type of the keys after decoding.
 * @typeParam TToValue - The type of the values after decoding.
 *
 * @param key - The codec for the map's keys.
 * @param value - The codec for the map's values.
 * @param config - Configuration options for encoding and decoding the map.
 * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding maps.
 *
 * @example
 * Encoding and decoding a map with a `u32` size prefix (default).
 * ```ts
 * const codec = getMapCodec(fixCodecSize(getUtf8Codec(), 5), getU8Codec());
 * const bytes = codec.encode(new Map([['alice', 42], ['bob', 5]]));
 * // 0x02000000616c6963652a626f62000005
 * //   |       |         | |         └── Value (5)
 * //   |       |         | └── Key ("bob", 5 bytes fixed, null-padded)
 * //   |       |         └── Value (42)
 * //   |       └── Key ("alice", 5 bytes fixed)
 * //   └── 4-byte prefix (2 entries)
 *
 * const map = codec.decode(bytes);
 * // new Map([['alice', 42], ['bob', 5]])
 * ```
 *
 * @example
 * Encoding and decoding a map with a `u16` size prefix.
 * ```ts
 * const codec = getMapCodec(fixCodecSize(getUtf8Codec(), 5), getU8Codec(), { size: getU16Codec() });
 * const bytes = codec.encode(new Map([['alice', 42], ['bob', 5]]));
 * // 0x0200616c6963652a626f62000005
 * //   |   |         | |         └── Value (5)
 * //   |   |         | └── Key ("bob", 5 bytes fixed, null-padded)
 * //   |   |         └── Value (42)
 * //   |   └── Key ("alice", 5 bytes fixed)
 * //   └── 2-byte prefix (2 entries)
 *
 * const map = codec.decode(bytes);
 * // new Map([['alice', 42], ['bob', 5]])
 * ```
 *
 * @example
 * Encoding and decoding a fixed-size map.
 * ```ts
 * const codec = getMapCodec(fixCodecSize(getUtf8Codec(), 5), getU8Codec(), { size: 2 });
 * const bytes = codec.encode(new Map([['alice', 42], ['bob', 5]]));
 * // 0x616c6963652a626f62000005
 * //   |         | |         └── Value (5)
 * //   |         | └── Key ("bob", 5 bytes fixed, null-padded)
 * //   |         └── Value (42)
 * //   └── Key ("alice", 5 bytes fixed)
 *
 * const map = codec.decode(bytes);
 * // new Map([['alice', 42], ['bob', 5]])
 * ```
 *
 * @example
 * Encoding and decoding a map with remainder size.
 * ```ts
 * const codec = getMapCodec(fixCodecSize(getUtf8Codec(), 5), getU8Codec(), { size: 'remainder' });
 * const bytes = codec.encode(new Map([['alice', 42], ['bob', 5]]));
 * // 0x616c6963652a626f62000005
 * //   |         | |         └── Value (5)
 * //   |         | └── Key ("bob", 5 bytes fixed, null-padded)
 * //   |         └── Value (42)
 * //   └── Key ("alice", 5 bytes fixed)
 * // No size prefix, the size is inferred from the remaining bytes.
 *
 * const map = codec.decode(bytes);
 * // new Map([['alice', 42], ['bob', 5]])
 * ```
 *
 * @remarks
 * Separate {@link getMapEncoder} and {@link getMapDecoder} functions are available.
 * ```ts
 * const bytes = getMapEncoder(fixCodecSize(getUtf8Encoder(), 5), getU8Encoder()).encode(new Map([['alice', 42]]));
 * const map = getMapDecoder(fixCodecSize(getUtf8Decoder(), 5), getU8Decoder()).decode(bytes);
 * ```
 *
 * @see {@link getMapEncoder}
 * @see {@link getMapDecoder}
 */
export declare function getMapCodec<TFromKey, TFromValue, TToKey extends TFromKey = TFromKey, TToValue extends TFromValue = TFromValue>(key: Codec<TFromKey, TToKey>, value: Codec<TFromValue, TToValue>, config: MapCodecConfig<NumberCodec> & {
    size: 0;
}): FixedSizeCodec<Map<TFromKey, TFromValue>, Map<TToKey, TToValue>, 0>;
export declare function getMapCodec<TFromKey, TFromValue, TToKey extends TFromKey = TFromKey, TToValue extends TFromValue = TFromValue>(key: FixedSizeCodec<TFromKey, TToKey>, value: FixedSizeCodec<TFromValue, TToValue>, config: MapCodecConfig<NumberCodec> & {
    size: number;
}): FixedSizeCodec<Map<TFromKey, TFromValue>, Map<TToKey, TToValue>>;
export declare function getMapCodec<TFromKey, TFromValue, TToKey extends TFromKey = TFromKey, TToValue extends TFromValue = TFromValue>(key: Codec<TFromKey, TToKey>, value: Codec<TFromValue, TToValue>, config?: MapCodecConfig<NumberCodec>): VariableSizeCodec<Map<TFromKey, TFromValue>, Map<TToKey, TToValue>>;
//# sourceMappingURL=map.d.ts.map