// ets_tracing: off import { _A, _E, _R } from "@effect-ts/core/Effect" import * as Ex from "@effect-ts/core/Effect/Exit" import * as E from "@effect-ts/core/Either" import { pipe } from "@effect-ts/core/Function" import * as C from "@effect-ts/system/Cause" import type { DataSourceAspect } from "../../DataSourceAspect/index.js" import * as BRS from "../BlockedRequests/index.js" import type { Continue } from "../Continue/index.js" import * as CONT from "../Continue/index.js" class Blocked { readonly _tag = "Blocked"; readonly [_R]!: (r: R) => never; readonly [_E]!: () => E; readonly [_A]!: () => A constructor( public readonly blockedRequests: BRS.BlockedRequests, public readonly cont: Continue ) {} } class Done { readonly _tag = "Done"; readonly [_A]!: () => A constructor(public readonly value: A) {} } class Fail { readonly _tag = "Fail"; readonly [_E]!: () => E constructor(public readonly cause: C.Cause) {} } export type Result = Blocked | Done | Fail /** * Folds over the successful or failed result. */ export function fold( failure: (e: E) => B, success: (a: A) => B ): (fa: Result) => Result { return (fa) => { switch (fa._tag) { case "Blocked": return blocked(fa.blockedRequests, pipe(fa.cont, CONT.fold(failure, success))) case "Done": return done(success(fa.value)) case "Fail": return pipe( C.failureOrCause(fa.cause), E.fold( (e) => done(failure(e)), (c) => fail(c) ) ) } } } /** * Maps the specified function over the successful value of this result. */ export function map(f: (a: A) => B) { return (self: Result): Result => { switch (self._tag) { case "Blocked": return blocked(self.blockedRequests, CONT.map(f)(self.cont)) case "Done": return done(f(self.value)) case "Fail": return fail(self.cause) } } } /** * Transforms all data sources with the specified data source aspect. */ export function mapDataSources(f: DataSourceAspect) { return (self: Result): Result => { switch (self._tag) { case "Blocked": return blocked( BRS.mapDataSources_(self.blockedRequests, f), CONT.mapDataSources_(self.cont, f) ) case "Done": return done(self.value) case "Fail": return fail(self.cause) } } } /** * Maps the specified function over the failed value of this result. */ export function mapError(f: (a: E) => E1) { return (self: Result): Result => { switch (self._tag) { case "Blocked": return blocked(self.blockedRequests, CONT.mapError(f)(self.cont)) case "Done": return done(self.value) case "Fail": return fail(C.map(f)(self.cause)) } } } /** * Constructs a result that is blocked on the specified requests with the * specified continuation. */ export function blocked( blockedRequests: BRS.BlockedRequests, cont: Continue ): Result { return new Blocked(blockedRequests, cont) } /** * Constructs a result that is done with the specified value. */ export function done(value: A): Result { return new Done(value) } /** * Constructs a result that is failed with the specified `Cause`. */ export function fail(cause: C.Cause): Result { return new Fail(cause) } /** * Lifts an `Either` into a result. */ export function fromEither(either: E.Either): Result { return E.fold_( either, (e) => fail(C.fail(e)), (a) => done(a) ) } /** * Lifts an `Exit` into a result. */ export function fromExit(exit: Ex.Exit): Result { return Ex.fold_( exit, (e) => fail(e), (a) => done(a) ) } /** * Provides this result with part of its required environment. */ export function provideSome(description: string, f: (r: R0) => R) { return (self: Result): Result => { switch (self._tag) { case "Blocked": return blocked( BRS.provideSome(description, f)(self.blockedRequests), CONT.provideSome(description, f)(self.cont) ) case "Done": return done(self.value) case "Fail": return fail(self.cause) } } }