import { Either, Left, Right } from "./either.ts" export class Controller { static isLeft(target: unknown): target is Left { return Either.isLeft(target) } static isRight(target: unknown): target is Right { return Either.isRight(target) } protected promise: Promise> protected resolve: (value: Either) => void protected reject: (value: L) => void constructor() { let _resolve: (value: Either) => void let _reject: (value: L) => void this.promise = new Promise((resolve, reject) => { _resolve = resolve _reject = reject }) this.resolve = _resolve! this.reject = _reject! } get value(): Promise> { return this.promise } async returnRight(value: R): Promise> { const right = new Right(value) this.resolve(right) return await Promise.resolve(right) } async returnLeft(value: L): Promise> { const left = new Left(value) this.resolve(left) return await Promise.resolve(left) } // oxlint-disable-next-line require-await async throw(value: L): Promise { const left = new Left(value) this.resolve(left) // oxlint-disable-next-line typescript/only-throw-error throw left } } type GetLeft = E extends Either ? L : never type GetRight = E extends Either ? R : never export const controllerFromEitherType = >(): Controller< GetLeft, GetRight > => { return new Controller, GetRight>() }