Packages

p

h8io.stages

operators

package operators

Ordering
  1. Alphabetic
Visibility
  1. Public
  2. Protected

Type Members

  1. final case class And[-I, +LO, +RO, +E](left: Stage[I, LO, E], right: Stage[I, RO, E]) extends BaseBinaryOperator[I, LO, RO, (LO, RO), E] with Product with Serializable

    A binary operator that applies left and right to the same input sequentially, producing a tuple of both outputs when both succeed.

    A binary operator that applies left and right to the same input sequentially, producing a tuple of both outputs when both succeed.

    The evaluation is short-circuit on the left side:

    • If left yields h8io.stages.Yield.Some, right is applied to the same input.
      • If right also yields Some, the result is Yield.Some((leftOut, rightOut), ...).
      • If right yields None, the result is Yield.None(mergedStatus, ...).
    • If left yields h8io.stages.Yield.None, right is **not** applied and the result is Yield.None(leftStatus, ...).

    Statuses from both sides are merged with combine.

    I

    the shared input type (contravariant)

    LO

    the left output type (covariant)

    RO

    the right output type (covariant)

    E

    the error type (covariant)

    left

    the first stage to apply

    right

    the second stage to apply when left succeeds

  2. final case class CompleteIfNone[I, O, E](alterand: Stage[I, O, E]) extends Decorator[I, O, E] with Product with Serializable

    A decorator that stops the pipeline when the inner stage produces no output.

    A decorator that stops the pipeline when the inner stage produces no output.

    When the inner stage yields h8io.stages.Yield.None with h8io.stages.Status.Success, CompleteIfNone upgrades the status to h8io.stages.Status.Complete, signaling that processing should not continue. All other h8io.stages.Yield variants are forwarded unchanged (with the evolution mapped to preserve the decorator).

    This is useful for stages that return None when their input stream is exhausted — wrapping them with CompleteIfNone turns the absence of output into a clean pipeline termination.

    I

    the input type

    O

    the output type

    E

    the error type

    alterand

    the inner stage to observe

  3. final case class IAnd[-I, +LO, +RO, +E](left: Stage[I, LO, E], right: Stage[I, RO, E]) extends BinaryOperator[Stage[I, LO, E], Stage[I, RO, E], I, (LO, RO), E] with Product with Serializable

    An independent binary operator that applies two stages to the same input simultaneously and combines their outputs into a tuple.

    An independent binary operator that applies two stages to the same input simultaneously and combines their outputs into a tuple.

    Both left and right are always applied — unlike And, which skips right if left produces no output.

    • If both stages yield h8io.stages.Yield.Some, the result is h8io.stages.Yield.Some((leftOut, rightOut), mergedStatus, ...).
    • If either stage yields h8io.stages.Yield.None, the result is h8io.stages.Yield.None(mergedStatus, ...).

    Statuses from both stages are merged with combine (i.e., leftStatus.combine(rightStatus)). The evolution pairs each branch's continuations symmetrically.

    I

    the shared input type (contravariant)

    LO

    the left output type (covariant)

    RO

    the right output type (covariant)

    E

    the error type (covariant)

    left

    the first stage

    right

    the second stage

  4. final case class Lift[I, O, E](alterand: Stage[I, O, E]) extends Alterator[Stage[I, O, E], I, Option[O], E] with Fruitful[I, Option[O], E] with Product with Serializable

    A decorator that wraps a stage's optional output into an Option, making the result always present.

    A decorator that wraps a stage's optional output into an Option, making the result always present.

    • If the inner stage yields h8io.stages.Yield.Some(v, ...), Lift produces h8io.stages.Yield.Some(Some(v), ...).
    • If the inner stage yields h8io.stages.Yield.None(...), Lift produces h8io.stages.Yield.Some(None, ...).

    Because Lift always emits a value, it extends h8io.stages.base.Fruitful. The evolution of the result is mapped so that every continuation stage is also wrapped in Lift, preserving the lifting semantics across the entire pipeline.

    Lift is the inverse of h8io.stages.projections.Unlift.

    I

    the input type

    O

    the inner output type; the outer output type becomes Option[O]

    E

    the error type

    alterand

    the inner stage whose output is optionally present

  5. final case class LocalSoftDeadline[-I, +O, +E](tsSupplier: () => Long, now: () => Long, duration: Long, alterand: Stage[I, O, E]) extends Decorator[I, O, E] with Product with Serializable

    A decorator that stops the pipeline after a given duration has elapsed since the last successful h8io.stages.Evolution transition.

    A decorator that stops the pipeline after a given duration has elapsed since the last successful h8io.stages.Evolution transition.

    Unlike h8io.stages.std.GlobalSoftDeadline, which measures time from the moment the stage is created, LocalSoftDeadline resets its clock on every onSuccess transition: the timestamp is captured at each apply call and preserved through the onSuccess transition, so the deadline window of the next stage starts from when the previous apply was evaluated. On onComplete and onError transitions the clock is also reset (to now), but the deadline is checked on the very next apply call.

    If the deadline is exceeded, the h8io.stages.Status of the current h8io.stages.Yield is upgraded to its break variant (e.g. SuccessComplete) by applying break to the status.

    If duration ≤ 0 the factory methods return h8io.stages.std.DeadEnd directly, ensuring the pipeline immediately terminates.

    I

    the input type (contravariant)

    O

    the output type (covariant)

    E

    the error type (covariant)

    tsSupplier

    a thunk that returns the timestamp captured at the last apply call

    now

    a supplier of the current time in nanoseconds

    duration

    the time budget in nanoseconds

    alterand

    the inner stage whose deadline is enforced

  6. final case class Loop[T, +E](alterand: Endo[T, E]) extends Decorator[T, T, E] with Product with Serializable

    A decorator that feeds the output of each successful step back as the input of the next, effectively looping the inner endomorphic stage until it stops.

    A decorator that feeds the output of each successful step back as the input of the next, effectively looping the inner endomorphic stage until it stops.

    The tail-recursive loop works as follows:

    • h8io.stages.Status.Success + h8io.stages.Yield.Some: the output becomes the new input and the loop continues with the onSuccess continuation.
    • h8io.stages.Status.Success + h8io.stages.Yield.None: no output was produced; the loop stops and emits Yield.None(Success, Loop(onComplete)).
    • h8io.stages.Status.Complete with no errors: the loop stops, converts the status back to Success, and selects the Complete continuation for the next outer invocation.
    • h8io.stages.Status.Complete with errors: the loop stops, preserves the errors, and selects the Complete continuation for the next outer invocation.

    This makes Loop suitable for in-process iterative computations (e.g., fixed-point iterations) where the result of one step seeds the next.

    T

    the value type (both input and output)

    E

    the error type (covariant)

    alterand

    the inner endomorphic stage T → T to loop

  7. final case class Or[-I, +LO, +RO, +E](left: Stage[I, LO, E], right: Stage[I, RO, E]) extends BinaryOperator[Stage[I, LO, E], Stage[I, RO, E], I, Either[LO, RO], E] with Product with Serializable

    A binary operator that tries left first; if left produces no output, it falls back to right, wrapping the result in scala.util.Either.

    A binary operator that tries left first; if left produces no output, it falls back to right, wrapping the result in scala.util.Either.

    Evaluation rules for a given input:

    • If left yields h8io.stages.Yield.Some, the result is Yield.Some(Left(leftOut), leftStatus, ...). right is **not** applied.
    • If left yields h8io.stages.Yield.None, right is applied:
      • right yields SomeYield.Some(Right(rightOut), mergedStatus, ...).
      • right yields NoneYield.None(mergedStatus, ...).

    Statuses are merged with combine.

    I

    the shared input type (contravariant)

    LO

    the left output type (covariant)

    RO

    the right output type (covariant)

    E

    the error type (covariant)

    left

    the preferred stage; tried first

    right

    the fallback stage; tried only when left yields no output

  8. final case class Repeat[-I, +O, +E](alterand: Stage[I, O, E]) extends Decorator[I, O, E] with Product with Serializable

    A decorator that keeps re-applying the inner stage (following its h8io.stages.Evolution.onSuccess transitions) until the stage signals completion or an error.

    A decorator that keeps re-applying the inner stage (following its h8io.stages.Evolution.onSuccess transitions) until the stage signals completion or an error.

    The loop is implemented with @tailrec so it does not grow the stack. The loop continues as long as the inner stage yields h8io.stages.Status.Success. It stops on h8io.stages.Status.Complete: if there are no errors the status is converted back to Success; if there are errors, the Complete status is preserved.

    Repeat is useful for driving stages like h8io.stages.std.Countdown that signal "batch complete" via Status.Complete and should be repeated as a whole unit.

    I

    the input type (contravariant)

    O

    the output type (covariant)

    E

    the error type (covariant)

    alterand

    the inner stage to repeat

  9. final case class Safe[-I, +O, +E](alterand: Stage[I, O, E]) extends Alterator[Stage[I, O, E], I, O, Either[Throwable, E]] with SafeStage[I, O, Either[Throwable, E]] with Product with Serializable

    A decorator that catches non-fatal exceptions thrown by the inner stage and converts them into h8io.stages.Status.Complete error values.

    A decorator that catches non-fatal exceptions thrown by the inner stage and converts them into h8io.stages.Status.Complete error values.

    The error type is widened from E to Either[Throwable, E]:

    • Errors already carried by the inner stage are wrapped as Right(e).
    • Exceptions caught during apply are reported as Left(throwable) in a Yield.None(Status.error(Left(e)), this).

    Only non-fatal exceptions (matched by scala.util.control.NonFatal) are caught; fatal errors such as OutOfMemoryError propagate normally.

    The evolution is mapped so that every continuation stage remains wrapped in Safe, maintaining exception safety across the entire pipeline.

    I

    the input type (contravariant)

    O

    the output type (covariant)

    E

    the original error type of the inner stage (covariant)

    alterand

    the inner stage whose exceptions should be caught

Value Members

  1. object And extends Serializable

    Companion object for And.

  2. object CompleteIfSome extends Decoration[Any, Any, Nothing]

    A h8io.stages.base.Decoration that stops the pipeline as soon as the decorated stage produces an output value.

    A h8io.stages.base.Decoration that stops the pipeline as soon as the decorated stage produces an output value.

    CompleteIfSome appends h8io.stages.std.Complete after the decorated stage via ~>. If the stage yields h8io.stages.Yield.Some, Complete immediately emits h8io.stages.Status.Complete, terminating the pipeline. If the stage yields h8io.stages.Yield.None, Complete is not reached and the pipeline continues normally.

    The singleton operates on Stage[Any, Any, Nothing] and can be cast to any concrete Decoration[I, O, E] via apply[I, O, E].

    Example:

    val stage: Stage[Int, Int, Nothing] = ...
    val completing: Stage[Int, Int, Nothing] = CompleteIfSome(stage)
    // Once stage produces a value, the pipeline stops.
  3. object IAnd extends Serializable

    Companion object for IAnd.

  4. object Identity extends Decoration[Any, Nothing, Nothing]

    The identity h8io.stages.base.Decoration: returns the decorated stage unchanged.

    The identity h8io.stages.base.Decoration: returns the decorated stage unchanged.

    Identity is useful as a no-op placeholder in decoration pipelines or when a h8io.stages.base.Decoration is required by an API but no transformation is needed.

    The singleton operates on Stage[Any, Nothing, Nothing] and can be safely cast to any concrete Decoration[I, O, E] via apply[I, O, E].

    Example:

    val dec: Decoration[String, Int, Nothing] = Identity[String, Int, Nothing]
  5. object KeepLastOutput

    A decorator that remembers the last output produced by the inner stage and re-emits it when the inner stage yields no value.

    A decorator that remembers the last output produced by the inner stage and re-emits it when the inner stage yields no value.

    The decorator has two internal states:

    • **None state** (initial): no output has been seen yet. The inner stage's h8io.stages.Yield.None is forwarded unchanged; a h8io.stages.Yield.Some is forwarded and transitions the wrapper to the Some state.
    • **Some state**: a previous output out is remembered. On every subsequent call the inner stage's last known output is emitted regardless of whether the inner stage yields Some or None. A new h8io.stages.Yield.Some updates the remembered value.

    In both states the evolution is mapped so that continuations remain wrapped in the appropriate KeepLastOutput variant, preserving the last-value semantics.

    The apply factory method always starts in the None state.

  6. object LocalSoftDeadline extends Serializable

    Companion object and factory for LocalSoftDeadline.

  7. object Or extends Serializable

    Companion object for Or.

Ungrouped