import * as Cause from "../Cause.js" import * as Chunk from "../Chunk.js" import * as Effect from "../Effect.js" import * as Exit from "../Exit.js" import { constFalse, constTrue, dual, pipe } from "../Function.js" import * as Option from "../Option.js" import { pipeArguments } from "../Pipeable.js" import type * as Take from "../Take.js" /** @internal */ const TakeSymbolKey = "effect/Take" /** @internal */ export const TakeTypeId: Take.TakeTypeId = Symbol.for( TakeSymbolKey ) as Take.TakeTypeId const takeVariance = { /* c8 ignore next */ _A: (_: never) => _, /* c8 ignore next */ _E: (_: never) => _ } /** @internal */ export class TakeImpl implements Take.Take { readonly [TakeTypeId] = takeVariance constructor(readonly exit: Exit.Exit, Option.Option>) { } pipe() { return pipeArguments(this, arguments) } } /** @internal */ export const chunk = (chunk: Chunk.Chunk): Take.Take => new TakeImpl(Exit.succeed(chunk)) /** @internal */ export const die = (defect: unknown): Take.Take => new TakeImpl(Exit.die(defect)) /** @internal */ export const dieMessage = (message: string): Take.Take => new TakeImpl(Exit.die(new Cause.RuntimeException(message))) /** @internal */ export const done = (self: Take.Take): Effect.Effect, Option.Option> => Effect.suspend(() => self.exit) /** @internal */ export const end: Take.Take = new TakeImpl(Exit.fail(Option.none())) /** @internal */ export const fail = (error: E): Take.Take => new TakeImpl(Exit.fail(Option.some(error))) /** @internal */ export const failCause = (cause: Cause.Cause): Take.Take => new TakeImpl(Exit.failCause(pipe(cause, Cause.map(Option.some)))) /** @internal */ export const fromEffect = (effect: Effect.Effect): Effect.Effect, never, R> => Effect.matchCause(effect, { onFailure: failCause, onSuccess: of }) /** @internal */ export const fromExit = (exit: Exit.Exit): Take.Take => new TakeImpl(pipe(exit, Exit.mapBoth({ onFailure: Option.some, onSuccess: Chunk.of }))) /** @internal */ export const fromPull = ( pull: Effect.Effect, Option.Option, R> ): Effect.Effect, never, R> => Effect.matchCause(pull, { onFailure: (cause) => Option.match(Cause.flipCauseOption(cause), { onNone: () => end, onSome: failCause }), onSuccess: chunk }) /** @internal */ export const isDone = (self: Take.Take): boolean => Exit.match(self.exit, { onFailure: (cause) => Option.isNone(Cause.flipCauseOption(cause)), onSuccess: constFalse }) /** @internal */ export const isFailure = (self: Take.Take): boolean => Exit.match(self.exit, { onFailure: (cause) => Option.isSome(Cause.flipCauseOption(cause)), onSuccess: constFalse }) /** @internal */ export const isSuccess = (self: Take.Take): boolean => Exit.match(self.exit, { onFailure: constFalse, onSuccess: constTrue }) /** @internal */ export const make = ( exit: Exit.Exit, Option.Option> ): Take.Take => new TakeImpl(exit) /** @internal */ export const match = dual< ( options: { readonly onEnd: () => Z readonly onFailure: (cause: Cause.Cause) => Z2 readonly onSuccess: (chunk: Chunk.Chunk) => Z3 } ) => (self: Take.Take) => Z | Z2 | Z3, ( self: Take.Take, options: { readonly onEnd: () => Z readonly onFailure: (cause: Cause.Cause) => Z2 readonly onSuccess: (chunk: Chunk.Chunk) => Z3 } ) => Z | Z2 | Z3 >(2, ( self: Take.Take, { onEnd, onFailure, onSuccess }: { readonly onEnd: () => Z readonly onFailure: (cause: Cause.Cause) => Z2 readonly onSuccess: (chunk: Chunk.Chunk) => Z3 } ): Z | Z2 | Z3 => Exit.match(self.exit, { onFailure: (cause) => Option.match(Cause.flipCauseOption(cause), { onNone: onEnd, onSome: onFailure }), onSuccess })) /** @internal */ export const matchEffect = dual< ( options: { readonly onEnd: Effect.Effect readonly onFailure: (cause: Cause.Cause) => Effect.Effect readonly onSuccess: (chunk: Chunk.Chunk) => Effect.Effect } ) => (self: Take.Take) => Effect.Effect, ( self: Take.Take, options: { readonly onEnd: Effect.Effect readonly onFailure: (cause: Cause.Cause) => Effect.Effect readonly onSuccess: (chunk: Chunk.Chunk) => Effect.Effect } ) => Effect.Effect >(2, ( self: Take.Take, { onEnd, onFailure, onSuccess }: { readonly onEnd: Effect.Effect readonly onFailure: (cause: Cause.Cause) => Effect.Effect readonly onSuccess: (chunk: Chunk.Chunk) => Effect.Effect } ): Effect.Effect => Exit.matchEffect(self.exit, { onFailure: (cause) => Option.match, Effect.Effect>(Cause.flipCauseOption(cause), { onNone: () => onEnd, onSome: onFailure }), onSuccess })) /** @internal */ export const map = dual< (f: (a: A) => B) => (self: Take.Take) => Take.Take, (self: Take.Take, f: (a: A) => B) => Take.Take >( 2, (self: Take.Take, f: (a: A) => B): Take.Take => new TakeImpl(pipe(self.exit, Exit.map(Chunk.map(f)))) ) /** @internal */ export const of = (value: A): Take.Take => new TakeImpl(Exit.succeed(Chunk.of(value))) /** @internal */ export const tap = dual< ( f: (chunk: Chunk.Chunk) => Effect.Effect ) => (self: Take.Take) => Effect.Effect, ( self: Take.Take, f: (chunk: Chunk.Chunk) => Effect.Effect ) => Effect.Effect >(2, ( self: Take.Take, f: (chunk: Chunk.Chunk) => Effect.Effect ): Effect.Effect => pipe(self.exit, Exit.forEachEffect(f), Effect.asVoid))