// ets_tracing: off import * as C from "../../../Cause/index.js" import * as A from "../../../Collections/Immutable/Chunk/index.js" import { _A, _E } from "../../../Effect/commons.js" import * as T from "../../../Effect/index.js" import * as Ex from "../../../Exit/index.js" import * as O from "../../../Option/index.js" import type { Pull } from "../Pull/index.js" /** * A `Take` represents a single `take` from a queue modeling a stream of * values. A `Take` may be a failure cause `Cause`, an chunk value `A` * or an end-of-stream marker. */ export class Take { readonly [_E]: () => E; readonly [_A]: () => A constructor(readonly exit: Ex.Exit, A.Chunk>) {} } /** * Transforms `Take[E, A]` to `Effect[R, E, B]`. */ export function done(self: Take): T.IO, A.Chunk> { return T.done(self.exit) } /** * Folds over the failure cause, success value and end-of-stream marker to * yield a value. */ export function fold_( self: Take, end: Z, error: (cause: C.Cause) => Z, value: (chunk: A.Chunk) => Z ): Z { return Ex.fold_( self.exit, (_) => O.fold_(C.flipCauseOption(_), () => end, error), value ) } /** * Folds over the failure cause, success value and end-of-stream marker to * yield a value. * * @ets_data_first fold_ */ export function fold( end: Z, error: (cause: C.Cause) => Z, value: (chunk: A.Chunk) => Z ) { return (self: Take) => fold_(self, end, error, value) } /** * Effectful version of `Take#fold`. * * Folds over the failure cause, success value and end-of-stream marker to * yield an effect. */ export function foldEffect_( self: Take, end: T.Effect, error: (cause: C.Cause) => T.Effect, value: (chunk: A.Chunk) => T.Effect ): T.Effect { return Ex.foldM_( self.exit, (_): T.Effect => O.fold_(C.flipCauseOption(_), () => end, error), value ) } /** * Effectful version of `Take#fold`. * * Folds over the failure cause, success value and end-of-stream marker to * yield an effect. * * @ets_data_first foldEffect_ */ export function foldEffect( end: T.Effect, error: (cause: C.Cause) => T.Effect, value: (chunk: A.Chunk) => T.Effect ) { return (self: Take) => foldEffect_(self, end, error, value) } /** * Checks if this `take` is done (`Take.end`). */ export function isDone(self: Take): boolean { return Ex.fold_( self.exit, (_) => O.isNone(C.flipCauseOption(_)), (_) => false ) } /** * Checks if this `take` is a failure. */ export function isFailure(self: Take): boolean { return Ex.fold_( self.exit, (_) => O.isSome(C.flipCauseOption(_)), (_) => false ) } /** * Checks if this `take` is a success. */ export function isSuccess(self: Take): boolean { return Ex.fold_( self.exit, (_) => false, (_) => true ) } /** * Transforms `Take` to `Take` by applying function `f`. */ export function map_(self: Take, f: (a: A) => B): Take { return new Take(Ex.map_(self.exit, A.map(f))) } /** * Transforms `Take` to `Take` by applying function `f`. * * @ets_data_first map_ */ export function map(f: (a: A) => B) { return (self: Take) => map_(self, f) } /** * Returns an effect that effectfully "peeks" at the success of this take. */ export function tap_( self: Take, f: (chunk: A.Chunk) => T.Effect ): T.Effect { return T.asUnit(Ex.forEach_(self.exit, f)) } /** * Returns an effect that effectfully "peeks" at the success of this take. * * @ets_data_first tap_ */ export function tap(f: (chunk: A.Chunk) => T.Effect) { return (self: Take) => tap_(self, f) } /** * Creates a `Take` with a singleton chunk. */ export function single(a: A): Take { return new Take(Ex.succeed(A.single(a))) } /** * Creates a `Take[Nothing, A]` with the specified chunk. */ export function chunk(as: A.Chunk): Take { return new Take(Ex.succeed(as)) } /** * Creates a failing `Take` with the specified failure. */ export function fail(e: E): Take { return new Take(Ex.fail(O.some(e))) } /** * Creates a failing `Take[E, Nothing]` with the specified cause. */ export function failCause(c: C.Cause): Take { return new Take(Ex.failCause(C.map_(c, O.some))) } /** * Creates an effect from `Effect` that does not fail, but succeeds with the `Take`. * Error from stream when pulling is converted to `Take.halt`. Creates a singleton chunk. */ export function fromEffect(effect: T.Effect): T.RIO> { return T.foldCause_(effect, (cause) => halt(cause), single) } /** * Creates effect from `Pull` that does not fail, but succeeds with the `Take`. * Error from stream when pulling is converted to `Take.halt`, end of stream to `Take.end`. */ export function fromPull(pull: Pull): T.RIO> { return T.foldCause_( pull, (_) => O.fold_(C.flipCauseOption(_), () => end, halt), chunk ) } /** * Creates a failing `Take` with the specified cause. */ export function halt(c: C.Cause): Take { return new Take(Ex.halt(C.map_(c, O.some))) } /** * Creates a failing `Take` with the specified throwable. */ export function die(e: E): Take { return new Take(Ex.die(e)) } /** * Creates a failing `Take` with the specified error message. */ export function dieMessage(msg: string): Take { return new Take(Ex.die(new C.RuntimeError(msg))) } /** * Creates a `Take` from `Exit`. */ export function fromExit(exit: Ex.Exit): Take { return new Take(Ex.map_(Ex.mapError_(exit, O.some), A.single)) } /** * End-of-stream marker */ export const end: Take = new Take(Ex.fail(O.none))