// Preserves Binary codec.

import { Position } from "./annotated";

export type ErrorType = 'DecodeError' | 'EncodeError' | 'ShortPacket';
export const ErrorType = Symbol.for('ErrorType');

export abstract class PreservesCodecError {
    abstract get [ErrorType](): ErrorType;

    static isCodecError(e: any, t: ErrorType): e is PreservesCodecError {
        return (e?.[ErrorType] === t);
    }
}

export class DecodeError extends Error {
    readonly pos: Position | undefined;

    get [ErrorType](): ErrorType { return 'DecodeError' }

    constructor(message: string, pos?: Position) {
        super(message);
        this.pos = pos;
    }

    static isDecodeError(e: any): e is DecodeError {
        return PreservesCodecError.isCodecError(e, 'DecodeError');
    }
}

export class EncodeError extends Error {
    get [ErrorType](): ErrorType { return 'EncodeError' }

    static isEncodeError(e: any): e is EncodeError {
        return PreservesCodecError.isCodecError(e, 'EncodeError');
    }

    readonly irritant: any;

    constructor(message: string, irritant: any) {
        super(message);
        this.irritant = irritant;
    }
}

export class ShortPacket extends DecodeError {
    get [ErrorType](): ErrorType { return 'ShortPacket' }

    static isShortPacket(e: any): e is ShortPacket {
        return PreservesCodecError.isCodecError(e, 'ShortPacket');
    }
}
