import { Consumer, Kind, Peek, Serializable, UnaryFunction } from '@jamashita/anden-type'; import { DeadConstructor, Schrodinger } from '@jamashita/genitore-schrodinger'; export type SReturnType = Exclude | ISuperposition | PromiseLike> | PromiseLike>; export interface ISuperposition extends Serializable { get(): Promise>; getErrors(): Set>; ifAlive(consumer: Consumer>): this; ifContradiction(consumer: Consumer): this; ifDead(consumer: Consumer): this; map( mapper: UnaryFunction, SReturnType>, ...errors: Array> ): ISuperposition; pass(accepted: Consumer>, declined: Consumer, thrown: Consumer): this; peek(peek: Peek): this; recover( mapper: UnaryFunction>, ...errors: Array> ): ISuperposition; terminate(): Promise>; transform( alive: UnaryFunction, SReturnType>, dead: UnaryFunction>, ...errors: Array> ): ISuperposition; } export const isSuperposition = (value: unknown): value is ISuperposition => { if (!Kind.isObject>(value)) { return false; } if (!Kind.isFunction(value.get)) { return false; } if (!Kind.isFunction(value.getErrors)) { return false; } if (!Kind.isFunction(value.terminate)) { return false; } if (!Kind.isFunction(value.map)) { return false; } if (!Kind.isFunction(value.recover)) { return false; } if (!Kind.isFunction(value.transform)) { return false; } if (!Kind.isFunction(value.ifAlive)) { return false; } if (!Kind.isFunction(value.ifDead)) { return false; } if (!Kind.isFunction(value.ifContradiction)) { return false; } if (!Kind.isFunction(value.pass)) { return false; } if (!Kind.isFunction(value.peek)) { return false; } return true; }; export const containsError = (err: unknown, errors: Set>): err is E => { return [...errors].some((error: DeadConstructor) => { return Kind.isClass>(err, error); }); };