All Downloads are FREE. Search and download functionalities are using the official Maven repository.

izumi.functional.bio.Bracket2.scala Maven / Gradle / Ivy

There is a newer version: 1.2.16
Show newest version
package izumi.functional.bio

trait Bracket2[F[+_, +_]] extends Error2[F] {
  def bracketCase[E, A, B](acquire: F[E, A])(release: (A, Exit[E, B]) => F[Nothing, Unit])(use: A => F[E, B]): F[E, B]

  def bracket[E, A, B](acquire: F[E, A])(release: A => F[Nothing, Unit])(use: A => F[E, B]): F[E, B] = {
    bracketCase(acquire)((a, _: Exit[E, B]) => release(a))(use)
  }

  def guaranteeCase[E, A](f: F[E, A], cleanup: Exit[E, A] => F[Nothing, Unit]): F[E, A] = {
    bracketCase(unit: F[E, Unit])((_, e: Exit[E, A]) => cleanup(e))(_ => f)
  }

  /**
    * Run release action only on a failure – _any failure_, INCLUDING interruption.
    * Do not run release action if `use` finished successfully.
    */
  final def bracketOnFailure[E, A, B](acquire: F[E, A])(cleanupOnFailure: (A, Exit.Failure[E]) => F[Nothing, Unit])(use: A => F[E, B]): F[E, B] = {
    bracketCase[E, A, B](acquire) {
      case (a, e: Exit.Failure[E]) => cleanupOnFailure(a, e)
      case _ => unit
    }(use)
  }

  /**
    * Run cleanup only on a failure – _any failure_, INCLUDING interruption.
    * Do not run cleanup if `use` finished successfully.
    */
  final def guaranteeOnFailure[E, A](f: F[E, A], cleanupOnFailure: Exit.Failure[E] => F[Nothing, Unit]): F[E, A] = {
    guaranteeCase[E, A](f, { case e: Exit.Failure[E] => cleanupOnFailure(e); case _ => unit })
  }

  /**
    * Run cleanup only on interruption.
    * Do not run cleanup if `use` finished successfully.
    */
  final def guaranteeOnInterrupt[E, A](f: F[E, A], cleanupOnInterruption: Exit.Interruption => F[Nothing, Unit]): F[E, A] = {
    guaranteeCase[E, A](f, { case e: Exit.Interruption => cleanupOnInterruption(e); case _ => unit })
  }

  /** Run cleanup on both _success_ and _failure_, if the failure IS NOT an interruption. */
  final def guaranteeExceptOnInterrupt[E, A](
    f: F[E, A],
    cleanupOnNonInterruption: Either[Exit.Termination, Either[Exit.Error[E], Exit.Success[A]]] => F[Nothing, Unit],
  ): F[E, A] = {
    guaranteeCase[E, A](
      f,
      {
        case e: Exit.Termination => cleanupOnNonInterruption(Left(e))
        case e: Exit.Error[E] => cleanupOnNonInterruption(Right(Left(e)))
        case e: Exit.Success[A] => cleanupOnNonInterruption(Right(Right(e)))
        case _: Exit.Interruption => unit
      },
    )
  }

  // defaults
  override def guarantee[E, A](f: F[E, A], cleanup: F[Nothing, Unit]): F[E, A] = {
    bracket(unit: F[E, Unit])(_ => cleanup)(_ => f)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy