import * as Equal from "../Equal.ts" import { format } from "../Formatter.ts" import { dual } from "../Function.ts" import * as Hash from "../Hash.ts" import { toJson } from "../Inspectable.ts" import type { Option } from "../Option.ts" import { hasProperty } from "../Predicate.ts" import type * as Result from "../Result.ts" import { SingleShotGen } from "../Utils.ts" import { PipeInspectableProto } from "./core.ts" import * as option from "./option.ts" const TypeId = "~effect/data/Result" const CommonProto = { [TypeId]: { /* v8 ignore next 2 */ _A: (_: never) => _, _E: (_: never) => _ }, ...PipeInspectableProto, [Symbol.iterator]() { return new SingleShotGen(this) } } const SuccessProto = Object.assign(Object.create(CommonProto), { _tag: "Success", _op: "Success", [Equal.symbol](this: Result.Success, that: unknown): boolean { return ( isResult(that) && isSuccess(that) && Equal.equals(this.success, that.success) ) }, [Hash.symbol](this: Result.Success) { return Hash.combine(Hash.hash(this._tag))(Hash.hash(this.success)) }, toString(this: Result.Success) { return `success(${format(this.success)})` }, toJSON(this: Result.Success) { return { _id: "Result", _tag: this._tag, value: toJson(this.success) } } }) const FailureProto = Object.assign(Object.create(CommonProto), { _tag: "Failure", _op: "Failure", [Equal.symbol](this: Result.Failure, that: unknown): boolean { return isResult(that) && isFailure(that) && Equal.equals(this.failure, that.failure) }, [Hash.symbol](this: Result.Failure) { return Hash.combine(Hash.hash(this._tag))(Hash.hash(this.failure)) }, toString(this: Result.Failure) { return `failure(${format(this.failure)})` }, toJSON(this: Result.Failure) { return { _id: "Result", _tag: this._tag, failure: toJson(this.failure) } } }) /** @internal */ export const isResult = (input: unknown): input is Result.Result => hasProperty(input, TypeId) /** @internal */ export const isFailure = (result: Result.Result): result is Result.Failure => result._tag === "Failure" /** @internal */ export const isSuccess = (result: Result.Result): result is Result.Success => result._tag === "Success" /** @internal */ export const fail = (failure: E): Result.Result => { const a = Object.create(FailureProto) a.failure = failure return a } /** @internal */ export const succeed = (success: A): Result.Result => { const a = Object.create(SuccessProto) a.success = success return a } /** @internal */ export const getFailure = (self: Result.Result): Option => isSuccess(self) ? option.none : option.some(self.failure) /** @internal */ export const getSuccess = (self: Result.Result): Option => isFailure(self) ? option.none : option.some(self.success) /** @internal */ export const fromOption: { (onNone: () => E): (self: Option) => Result.Result (self: Option, onNone: () => E): Result.Result } = dual( 2, (self: Option, onNone: () => E): Result.Result => option.isNone(self) ? fail(onNone()) : succeed(self.value) )