import { dual } from "../../Function.js"
import type * as Option from "../../Option.js"
import { hasProperty } from "../../Predicate.js"
import type * as UpstreamPullStrategy from "../../UpstreamPullStrategy.js"
import * as OpCodes from "../opCodes/channelUpstreamPullStrategy.js"
/** @internal */
const UpstreamPullStrategySymbolKey = "effect/ChannelUpstreamPullStrategy"
/** @internal */
export const UpstreamPullStrategyTypeId: UpstreamPullStrategy.UpstreamPullStrategyTypeId = Symbol.for(
UpstreamPullStrategySymbolKey
) as UpstreamPullStrategy.UpstreamPullStrategyTypeId
const upstreamPullStrategyVariance = {
/* c8 ignore next */
_A: (_: never) => _
}
/** @internal */
const proto = {
[UpstreamPullStrategyTypeId]: upstreamPullStrategyVariance
}
/** @internal */
export const PullAfterNext = (emitSeparator: Option.Option): UpstreamPullStrategy.UpstreamPullStrategy => {
const op = Object.create(proto)
op._tag = OpCodes.OP_PULL_AFTER_NEXT
op.emitSeparator = emitSeparator
return op
}
/** @internal */
export const PullAfterAllEnqueued = (
emitSeparator: Option.Option
): UpstreamPullStrategy.UpstreamPullStrategy => {
const op = Object.create(proto)
op._tag = OpCodes.OP_PULL_AFTER_ALL_ENQUEUED
op.emitSeparator = emitSeparator
return op
}
/** @internal */
export const isUpstreamPullStrategy = (u: unknown): u is UpstreamPullStrategy.UpstreamPullStrategy =>
hasProperty(u, UpstreamPullStrategyTypeId)
/** @internal */
export const isPullAfterNext = (
self: UpstreamPullStrategy.UpstreamPullStrategy
): self is UpstreamPullStrategy.PullAfterNext => self._tag === OpCodes.OP_PULL_AFTER_NEXT
/** @internal */
export const isPullAfterAllEnqueued = (
self: UpstreamPullStrategy.UpstreamPullStrategy
): self is UpstreamPullStrategy.PullAfterAllEnqueued => self._tag === OpCodes.OP_PULL_AFTER_ALL_ENQUEUED
/** @internal */
export const match = dual<
(
options: {
readonly onNext: (emitSeparator: Option.Option) => Z
readonly onAllEnqueued: (emitSeparator: Option.Option) => Z
}
) => (self: UpstreamPullStrategy.UpstreamPullStrategy) => Z,
(
self: UpstreamPullStrategy.UpstreamPullStrategy,
options: {
readonly onNext: (emitSeparator: Option.Option) => Z
readonly onAllEnqueued: (emitSeparator: Option.Option) => Z
}
) => Z
>(2, (
self: UpstreamPullStrategy.UpstreamPullStrategy,
{ onAllEnqueued, onNext }: {
readonly onNext: (emitSeparator: Option.Option) => Z
readonly onAllEnqueued: (emitSeparator: Option.Option) => Z
}
): Z => {
switch (self._tag) {
case OpCodes.OP_PULL_AFTER_NEXT: {
return onNext(self.emitSeparator)
}
case OpCodes.OP_PULL_AFTER_ALL_ENQUEUED: {
return onAllEnqueued(self.emitSeparator)
}
}
})