import { type FixedUint, Uint64, Uint8 } from "low-level";
import { Uint } from "low-level";
import type { AnyObj, EncodeableObj, FixedUintConstructor } from "./types.js";
export declare abstract class DataEncoder {
    readonly key: string;
    readonly hashRemove: boolean;
    constructor(key: string, hashRemove?: boolean);
    abstract encode(v: any): Uint[] | null;
    abstract decode(v: Uint): {
        data: any;
        length: number;
    } | null;
}
declare class ArrayEncoder extends DataEncoder {
    protected readonly prefixLength: number | "unlimited";
    protected readonly targetObject: EncodeableObj;
    constructor(key: string, prefixLength: number | "unlimited", targetObject: EncodeableObj, hashRemove?: boolean);
    encode(array: any[]): Uint[];
    decode(arrayDataWithPrefix: Uint): {
        data: any[];
        length: number;
    };
}
declare class ObjectEncoder extends DataEncoder {
    protected readonly targetObject: EncodeableObj;
    constructor(key: string, targetObject: EncodeableObj, hashRemove?: boolean);
    encode(object: AnyObj): Uint[];
    decode(hexData: Uint): {
        data: any;
        length: number;
    };
}
declare class BigIntEncoder extends DataEncoder {
    readonly prefixLength = 1;
    encode(value: Uint64): Uint[];
    decode(hexDataWithPrefix: Uint): {
        data: Uint64;
        length: number;
    } | null;
}
declare class BoolEncoder extends DataEncoder {
    readonly fixedLength = 1;
    encode(value: boolean): Uint8[];
    decode(hexData: Uint): {
        data: boolean;
        length: number;
    } | null;
}
declare class FixedUintEncoder<T extends FixedUint> extends DataEncoder {
    protected readonly CLS: FixedUintConstructor<T>;
    constructor(CLS: FixedUintConstructor<T>, key: string, hashRemove?: boolean);
    encode(v: Uint): Uint[];
    decode(hexData: Uint): {
        data: T;
        length: number;
    } | null;
}
type CustomEncodeFn<T = any> = (value: T) => Uint;
type CustomDecodeFn<T = any> = (hexData: Uint) => T;
type CustomEncoderLengthArg = {
    type: "prefix";
    val: number | "unlimited";
} | {
    type: "fixed";
    val: number;
};
declare class CustomEncoder<T = Uint> extends DataEncoder {
    protected readonly encodeFN?: CustomEncodeFn<T> | undefined;
    protected readonly decodeFN?: CustomDecodeFn<T> | undefined;
    protected readonly prefixLength?: number | "unlimited";
    protected readonly fixedLength?: number;
    constructor(key: string, length: CustomEncoderLengthArg, hashRemove?: boolean);
    constructor(key: string, length: CustomEncoderLengthArg, hashRemove: boolean, encodeFN: CustomEncodeFn<T>, decodeFN: CustomDecodeFn<T>);
    encode(value: T): Uint[] | null;
    decode(hexData: Uint): {
        data: T;
        length: number;
    } | null;
}
export declare function BE<T extends FixedUint>(CLS: FixedUintConstructor<T>, key: string, hashRemove?: boolean): FixedUintEncoder<T>;
/**
 * Basic Types
 */
export declare namespace BE {
    const BigInt: (key: string, hashRemove?: boolean | undefined) => BigIntEncoder;
    const Bool: (key: string, hashRemove?: boolean | undefined) => BoolEncoder;
    const Array: (key: string, prefixLength: number | "unlimited", targetObject: EncodeableObj<import("./types.js").EncodeableObjInstance>, hashRemove?: boolean | undefined) => ArrayEncoder;
    const Object: (key: string, targetObject: EncodeableObj<import("./types.js").EncodeableObjInstance>, hashRemove?: boolean | undefined) => ObjectEncoder;
    function Custom(key: string, length: CustomEncoderLengthArg, hashRemove?: boolean): CustomEncoder<Uint>;
    function Custom<T>(key: string, length: CustomEncoderLengthArg, hashRemove: boolean, encodeFN: CustomEncodeFn<T>, decodeFN: CustomDecodeFn<T>): CustomEncoder<T>;
}
/**
 * More Advanced Types
 */
export declare namespace BE {
    function Str(key: string, hashRemove?: boolean): CustomEncoder<string>;
}
export { BE as BEncoder };
