import type { Arrayable } from "type-fest";
import type { Decoder } from "./decoder.js";
/**
 * TLV-VALUE decoder that understands Packet Format v0.3 evolvability guidelines.
 * @typeParam T - Target type being decoded.
 */
export declare class EvDecoder<T> {
    private readonly typeName;
    private readonly topTT;
    private readonly rules;
    private readonly requiredTT;
    private nextOrder;
    private isCritical;
    private unknownHandler?;
    /** Callbacks before decoding TLV-VALUE. */
    readonly beforeObservers: Array<EvDecoder.TlvObserver<T>>;
    /** Callbacks after decoding TLV-VALUE. */
    readonly afterObservers: Array<EvDecoder.TlvObserver<T>>;
    /**
     * Constructor.
     * @param typeName - type name, used in error messages.
     * @param topTT - If specified, the top-level TLV-TYPE will be checked to be in this list.
     */
    constructor(typeName: string, topTT?: Arrayable<number>);
    applyDefaultsToRuleOptions({ order, required, repeat, }?: EvDecoder.RuleOptions): Required<EvDecoder.RuleOptions>;
    /**
     * Add a decoding rule.
     * @param tt - TLV-TYPE to match this rule.
     * @param cb - Callback or nested EvDecoder to handle element TLV.
     * @param opts - Additional rule options.
     */
    add(tt: number, cb: EvDecoder.ElementDecoder<T> | EvDecoder<T>, opts?: Partial<EvDecoder.RuleOptions>): this;
    /** Set callback to determine whether TLV-TYPE is critical. */
    setIsCritical(cb: EvDecoder.IsCritical): this;
    /** Set callback to handle unknown elements. */
    setUnknown(cb: EvDecoder.UnknownElementHandler<T>): this;
    /** Decode TLV to target object. */
    decode<R extends T = T>(target: R, decoder: Decoder): R;
    /** Decode TLV-VALUE to target object. */
    decodeValue<R extends T = T>(target: R, vd: Decoder): R;
    private decodeV;
    private handleUnrecognized;
}
export declare namespace EvDecoder {
    /** Invoked when a matching TLV element is found. */
    type ElementDecoder<T> = (target: T, tlv: Decoder.Tlv) => void;
    interface RuleOptions {
        /**
         * Expected order of appearance.
         *
         * @remarks
         * When using this option, it should be specified for all rules in a EvDecoder.
         *
         * @defaultValue
         * The order in which rules were added to EvDecoder.
         */
        order?: number;
        /**
         * Whether TLV element must appear at least once.
         * @defaultValue `false`
         */
        required?: boolean;
        /**
         * Whether TLV element may appear more than once.
         * @defaultValue `false`
         */
        repeat?: boolean;
    }
    /**
     * Invoked when a TLV element does not match any rule.
     * @param order - Order number of the last recognized TLV element.
     * @returns `true` if this TLV element is accepted; `false` to follow evolvability guidelines.
     */
    type UnknownElementHandler<T> = (target: T, tlv: Decoder.Tlv, order: number) => boolean;
    /**
     * Function to determine whether a TLV-TYPE number is "critical".
     * Unrecognized or out-of-order TLV element with a critical TLV-TYPE number causes decoding error.
     */
    type IsCritical = (tt: number) => boolean;
    /**
     * IsCritical callback that always returns `false`.
     * Any unrecognized or out-of-order TLV elements would be ignored.
     */
    const neverCritical: IsCritical;
    /**
     * IsCritical callback that always returns `true`.
     * Any unrecognized or out-of-order TLV elements would cause an error.
     */
    const alwaysCritical: IsCritical;
    /**
     * Callback before or after decoding TLV-VALUE.
     * @param target - Target object.
     * @param topTlv - Top-level TLV element, available in EVD.decode but unavailable in EVD.decodeValue.
     */
    type TlvObserver<T> = (target: T, topTlv?: Decoder.Tlv) => void;
}
