/** * @tsplus type Result */ export type Result = Success | SuccessWithWarning | Failure /** * @tsplus type ResultOps */ export interface ResultOps {} export const Result: ResultOps = {} export const _T = Symbol.for("@tsplus/runtime/Result/_T") export type _T = typeof _T /** * @tsplus type Result/Success */ export interface Success { readonly [_T]?: { _W: (_: never) => never _E: (_: never) => never _A: (_: never) => A } readonly _tag: "Success" readonly success: A } /** * @tsplus type Result/SuccessWithWarning */ export interface SuccessWithWarning { readonly [_T]?: { _W: (_: never) => W _E: (_: never) => never _A: (_: never) => A } readonly _tag: "SuccessWithWarning" readonly success: A readonly warning: W } /** * @tsplus type Result/Failure */ export interface Failure { readonly [_T]?: { _W: (_: never) => never _E: (_: never) => E _A: (_: never) => never } readonly _tag: "Failure" readonly failure: E } /** * @tsplus unify Result/Success * @tsplus unify Result/SuccessWithWarning * @tsplus unify Result/Failure */ export function unifyResult>( self: X ): Result< [X] extends [{ readonly [_T]?: { _W: (_: never) => infer W _E: (_: never) => infer E _A: (_: never) => infer A } }] ? W : never, [X] extends [{ readonly [_T]?: { _W: (_: never) => infer W _E: (_: never) => infer E _A: (_: never) => infer A } }] ? E : never, [X] extends [{ readonly [_T]?: { _W: (_: never) => infer W _E: (_: never) => infer E _A: (_: never) => infer A } }] ? A : never > { return self } /** * @tsplus fluent Result fold */ export function fold( self: Result, onSuccess: (a: A, w: Maybe) => T0, onFailure: (e: E) => T1 ) { switch (self._tag) { case "Failure": { return onFailure(self.failure) } case "Success": { return onSuccess(self.success, Maybe.none) } case "SuccessWithWarning": { return onSuccess(self.success, Maybe.some(self.warning)) } } } /** * @tsplus static ResultOps success */ export function success(result: A): Result export function success(result: A, warning: Maybe): Result export function success(result: A, warning?: Maybe): Result { if (warning && warning.isSome()) { return { _tag: "SuccessWithWarning", success: result, warning: warning.value } } return { _tag: "Success", success: result } } /** * @tsplus static ResultOps fail */ export function fail(error: E): Result { return { _tag: "Failure", failure: error } } /** * @tsplus static ResultOps successWithWarning */ export function successWithWarning(result: A, warning: W): Result { return { _tag: "SuccessWithWarning", success: result, warning } } /** * @tsplus fluent Result isSuccess */ export function isSuccess(self: Result): self is Success { return self._tag === "Success" } /** * @tsplus fluent Result isFailure */ export function isFailure(self: Result): self is Failure { return self._tag === "Failure" } /** * @tsplus fluent Result isSuccessWihWarning */ export function isSuccessWihWarning( self: Result ): self is SuccessWithWarning { return self._tag === "SuccessWithWarning" } /** * @tsplus fluent Result getSuccess */ export function getSuccess(self: Result) { return self.isFailure() ? Maybe.none : Maybe.some(self.success) } /** * @tsplus fluent Result getFailure */ export function getFailure(self: Result) { return self.isFailure() ? Maybe.some(self.failure) : Maybe.none } /** * @tsplus fluent Result getWarning */ export function getWarning(self: Result) { return self.isSuccessWihWarning() ? Maybe.some(self.warning) : Maybe.none } /** * @tsplus fluent Result getWarningOrFailure */ export function getWarningOrError(self: Result) { return self.fold((_, w) => w.map(Either.left), (e) => Maybe.some(Either.right(e))) } /** * @tsplus fluent Result map */ export function map_(self: Result, f: (a: A) => B): Result { return self.fold((a, w) => Result.success(f(a), w), Result.fail) }