mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
6.4 KiB
199 lines
6.4 KiB
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<out A, out E = never> implements Take.Take<A, E> {
|
|
readonly [TakeTypeId] = takeVariance
|
|
constructor(readonly exit: Exit.Exit<Chunk.Chunk<A>, Option.Option<E>>) {
|
|
}
|
|
pipe() {
|
|
return pipeArguments(this, arguments)
|
|
}
|
|
}
|
|
|
|
/** @internal */
|
|
export const chunk = <A>(chunk: Chunk.Chunk<A>): Take.Take<A> => new TakeImpl(Exit.succeed(chunk))
|
|
|
|
/** @internal */
|
|
export const die = (defect: unknown): Take.Take<never> => new TakeImpl(Exit.die(defect))
|
|
|
|
/** @internal */
|
|
export const dieMessage = (message: string): Take.Take<never> =>
|
|
new TakeImpl(Exit.die(new Cause.RuntimeException(message)))
|
|
|
|
/** @internal */
|
|
export const done = <A, E>(self: Take.Take<A, E>): Effect.Effect<Chunk.Chunk<A>, Option.Option<E>> =>
|
|
Effect.suspend(() => self.exit)
|
|
|
|
/** @internal */
|
|
export const end: Take.Take<never> = new TakeImpl(Exit.fail(Option.none()))
|
|
|
|
/** @internal */
|
|
export const fail = <E>(error: E): Take.Take<never, E> => new TakeImpl(Exit.fail(Option.some(error)))
|
|
|
|
/** @internal */
|
|
export const failCause = <E>(cause: Cause.Cause<E>): Take.Take<never, E> =>
|
|
new TakeImpl(Exit.failCause(pipe(cause, Cause.map(Option.some))))
|
|
|
|
/** @internal */
|
|
export const fromEffect = <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<Take.Take<A, E>, never, R> =>
|
|
Effect.matchCause(effect, { onFailure: failCause, onSuccess: of })
|
|
|
|
/** @internal */
|
|
export const fromExit = <A, E>(exit: Exit.Exit<A, E>): Take.Take<A, E> =>
|
|
new TakeImpl(pipe(exit, Exit.mapBoth({ onFailure: Option.some, onSuccess: Chunk.of })))
|
|
|
|
/** @internal */
|
|
export const fromPull = <A, E, R>(
|
|
pull: Effect.Effect<Chunk.Chunk<A>, Option.Option<E>, R>
|
|
): Effect.Effect<Take.Take<A, E>, never, R> =>
|
|
Effect.matchCause(pull, {
|
|
onFailure: (cause) =>
|
|
Option.match(Cause.flipCauseOption(cause), {
|
|
onNone: () => end,
|
|
onSome: failCause
|
|
}),
|
|
onSuccess: chunk
|
|
})
|
|
|
|
/** @internal */
|
|
export const isDone = <A, E>(self: Take.Take<A, E>): boolean =>
|
|
Exit.match(self.exit, {
|
|
onFailure: (cause) => Option.isNone(Cause.flipCauseOption(cause)),
|
|
onSuccess: constFalse
|
|
})
|
|
|
|
/** @internal */
|
|
export const isFailure = <A, E>(self: Take.Take<A, E>): boolean =>
|
|
Exit.match(self.exit, {
|
|
onFailure: (cause) => Option.isSome(Cause.flipCauseOption(cause)),
|
|
onSuccess: constFalse
|
|
})
|
|
|
|
/** @internal */
|
|
export const isSuccess = <A, E>(self: Take.Take<A, E>): boolean =>
|
|
Exit.match(self.exit, {
|
|
onFailure: constFalse,
|
|
onSuccess: constTrue
|
|
})
|
|
|
|
/** @internal */
|
|
export const make = <A, E>(
|
|
exit: Exit.Exit<Chunk.Chunk<A>, Option.Option<E>>
|
|
): Take.Take<A, E> => new TakeImpl(exit)
|
|
|
|
/** @internal */
|
|
export const match = dual<
|
|
<Z, E, Z2, A, Z3>(
|
|
options: {
|
|
readonly onEnd: () => Z
|
|
readonly onFailure: (cause: Cause.Cause<E>) => Z2
|
|
readonly onSuccess: (chunk: Chunk.Chunk<A>) => Z3
|
|
}
|
|
) => (self: Take.Take<A, E>) => Z | Z2 | Z3,
|
|
<A, E, Z, Z2, Z3>(
|
|
self: Take.Take<A, E>,
|
|
options: {
|
|
readonly onEnd: () => Z
|
|
readonly onFailure: (cause: Cause.Cause<E>) => Z2
|
|
readonly onSuccess: (chunk: Chunk.Chunk<A>) => Z3
|
|
}
|
|
) => Z | Z2 | Z3
|
|
>(2, <A, E, Z, Z2, Z3>(
|
|
self: Take.Take<A, E>,
|
|
{ onEnd, onFailure, onSuccess }: {
|
|
readonly onEnd: () => Z
|
|
readonly onFailure: (cause: Cause.Cause<E>) => Z2
|
|
readonly onSuccess: (chunk: Chunk.Chunk<A>) => 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<
|
|
<Z, E2, R, E, Z2, R2, A, Z3, E3, R3>(
|
|
options: {
|
|
readonly onEnd: Effect.Effect<Z, E2, R>
|
|
readonly onFailure: (cause: Cause.Cause<E>) => Effect.Effect<Z2, E2, R2>
|
|
readonly onSuccess: (chunk: Chunk.Chunk<A>) => Effect.Effect<Z3, E3, R3>
|
|
}
|
|
) => (self: Take.Take<A, E>) => Effect.Effect<Z | Z2 | Z3, E2 | E | E3, R | R2 | R3>,
|
|
<A, E, Z, E2, R, Z2, R2, Z3, E3, R3>(
|
|
self: Take.Take<A, E>,
|
|
options: {
|
|
readonly onEnd: Effect.Effect<Z, E2, R>
|
|
readonly onFailure: (cause: Cause.Cause<E>) => Effect.Effect<Z2, E2, R2>
|
|
readonly onSuccess: (chunk: Chunk.Chunk<A>) => Effect.Effect<Z3, E3, R3>
|
|
}
|
|
) => Effect.Effect<Z | Z2 | Z3, E2 | E | E3, R | R2 | R3>
|
|
>(2, <A, E, Z, E2, R, Z2, R2, Z3, E3, R3>(
|
|
self: Take.Take<A, E>,
|
|
{ onEnd, onFailure, onSuccess }: {
|
|
readonly onEnd: Effect.Effect<Z, E2, R>
|
|
readonly onFailure: (cause: Cause.Cause<E>) => Effect.Effect<Z2, E2, R2>
|
|
readonly onSuccess: (chunk: Chunk.Chunk<A>) => Effect.Effect<Z3, E3, R3>
|
|
}
|
|
): Effect.Effect<Z | Z2 | Z3, E2 | E | E3, R | R2 | R3> =>
|
|
Exit.matchEffect(self.exit, {
|
|
onFailure: (cause) =>
|
|
Option.match<Cause.Cause<E>, Effect.Effect<Z | Z2, E2 | E, R | R2>>(Cause.flipCauseOption(cause), {
|
|
onNone: () => onEnd,
|
|
onSome: onFailure
|
|
}),
|
|
onSuccess
|
|
}))
|
|
|
|
/** @internal */
|
|
export const map = dual<
|
|
<A, B>(f: (a: A) => B) => <E>(self: Take.Take<A, E>) => Take.Take<B, E>,
|
|
<A, E, B>(self: Take.Take<A, E>, f: (a: A) => B) => Take.Take<B, E>
|
|
>(
|
|
2,
|
|
<A, E, B>(self: Take.Take<A, E>, f: (a: A) => B): Take.Take<B, E> =>
|
|
new TakeImpl(pipe(self.exit, Exit.map(Chunk.map(f))))
|
|
)
|
|
|
|
/** @internal */
|
|
export const of = <A>(value: A): Take.Take<A> => new TakeImpl(Exit.succeed(Chunk.of(value)))
|
|
|
|
/** @internal */
|
|
export const tap = dual<
|
|
<A, X, E2, R>(
|
|
f: (chunk: Chunk.Chunk<A>) => Effect.Effect<X, E2, R>
|
|
) => <E>(self: Take.Take<A, E>) => Effect.Effect<void, E2 | E, R>,
|
|
<A, E, X, E2, R>(
|
|
self: Take.Take<A, E>,
|
|
f: (chunk: Chunk.Chunk<A>) => Effect.Effect<X, E2, R>
|
|
) => Effect.Effect<void, E2 | E, R>
|
|
>(2, <A, E, X, E2, R>(
|
|
self: Take.Take<A, E>,
|
|
f: (chunk: Chunk.Chunk<A>) => Effect.Effect<X, E2, R>
|
|
): Effect.Effect<void, E2 | E, R> => pipe(self.exit, Exit.forEachEffect(f), Effect.asVoid))
|
|
|