Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package kyo
import java.io.IOException
import kyo.kernel.Boundary
import kyo.kernel.Reducible
import scala.annotation.tailrec
import scala.concurrent.Future
import scala.reflect.ClassTag
import scala.util.Failure
import scala.util.NotGiven
import scala.util.Success
extension (kyoObject: Kyo.type)
/** Acquires a resource and ensures its release.
*
* @param acquire
* The effect to acquire the resource
* @param release
* The effect to release the resource
* @return
* An effect that manages the resource lifecycle using Resource and IO effects
*/
def acquireRelease[A, S](acquire: => A < S)(release: A => Unit < Async)(using Frame): A < (S & Resource & IO) =
Resource.acquireRelease(acquire)(release)
/** Adds a finalizer to the current effect using Resource.
*
* @param finalizer
* The effect to add as a finalizer
* @return
* An effect that ensures the finalizer is executed when the effect is completed
*/
def addFinalizer(finalizer: => Unit < Async)(using Frame): Unit < (Resource & IO) =
Resource.ensure(finalizer)
/** Creates an asynchronous effect that can be completed by the given register function.
*
* @param register
* A function that takes an asynchronous effect and registers it to be completed
* @return
* An effect that can be completed by the given register function
*/
def async[A](register: (A < Async => Unit) => Unit < Async)(
using
Flat[A],
Frame
): A < Async =
for
promise <- Promise.init[Nothing, A]
registerFn = (eff: A < Async) =>
val effFiber = Async.run(eff)
val updatePromise =
effFiber.map(_.onComplete(a => promise.completeDiscard(a)))
val updatePromiseIO = Async.run(updatePromise).unit
import AllowUnsafe.embrace.danger
IO.Unsafe.run(updatePromiseIO).eval
_ <- register(registerFn)
a <- promise.get
yield a
/** Creates an effect that attempts to run the given effect and handles any exceptions that occur to Abort[Throwable].
*
* @param effect
* The effect to attempt to run
* @return
* An effect that attempts to run the given effect and handles any exceptions that occur
*/
def attempt[A, S](effect: => A < S)(using Flat[A], Frame): A < (S & Abort[Throwable]) =
Abort.catching[Throwable](effect)
/** Collects elements from a sequence using a partial function and returns a new sequence.
*
* @param sequence
* The sequence to collect elements from
* @param useElement
* A partial function to apply to each element of the sequence
* @return
* A new sequence with elements collected using the partial function
*/
def collect[A, S, A1](sequence: Seq[A])(useElement: PartialFunction[A, A1 < S])(using Frame): Seq[A1] < S =
Kyo.collect(sequence.collect(useElement))
/** Prints a message to the console.
*
* @param message
* The message to print
* @return
* An effect that prints the message to the console
*/
def debugln(message: String)(using Frame): Unit < (IO & Abort[IOException]) =
Console.println(message)
/** Creates an effect that fails with Abort[E].
*
* @param error
* The error to fail with
* @return
* An effect that fails with the given error
*/
def fail[E](error: => E)(using Frame): Nothing < Abort[E] =
Abort.fail(error)
/** Applies a function to each element in parallel and returns a new sequence with the results.
*
* @param sequence
* The sequence to apply the function to
* @param useElement
* A function to apply to each element of the sequence
* @return
* A new sequence with elements collected using the function
*/
def foreachPar[E, A, S, A1, Ctx](sequence: Seq[A])(useElement: A => A1 < (Abort[E] & Async & Ctx))(
using
flat: Flat[A1],
boundary: Boundary[Ctx, Async & Abort[E]],
frame: Frame
): Seq[A1] < (Abort[E] & Async & Ctx) =
Async.parallel[E, A1, Ctx](sequence.map(useElement))
/** Applies a function to each element in parallel and discards the results.
*
* @param sequence
* The sequence to apply the function to
* @param useElement
* A function to apply to each element of the sequence
* @return
* Discards the results of the function application and returns Unit
*/
def foreachParDiscard[E, A, S, A1, Ctx](sequence: Seq[A])(useElement: A => A1 < (Abort[E] & Async & Ctx))(
using
flat: Flat[A1],
boundary: Boundary[Ctx, Async & Abort[E]],
frame: Frame
): Unit < (Abort[E] & Async & Ctx) =
foreachPar(sequence)(useElement).unit
/** Creates an effect from an AutoCloseable resource.
*
* @param closeable
* The AutoCloseable resource to create an effect from
* @return
* An effect that manages the resource lifecycle using Resource and IO effects
*/
def fromAutoCloseable[A <: AutoCloseable, S](closeable: => A < S)(using Frame): A < (S & Resource & IO) =
acquireRelease(closeable)(c => IO(c.close()))
/** Creates an effect from an Either[E, A] and handles Left[E] to Abort[E].
*
* @param either
* The Either[E, A] to create an effect from
* @return
* An effect that attempts to run the given effect and handles Left[E] to Abort[E].
*/
def fromEither[E, A](either: Either[E, A])(using Frame): A < Abort[E] =
Abort.get(either)
/** Creates an effect from an Option[A] and handles None to Abort[Absent].
*
* @param option
* The Option[A] to create an effect from
* @return
* An effect that attempts to run the given effect and handles None to Abort[Absent].
*/
def fromOption[A](option: Option[A])(using Frame): A < Abort[Absent] =
Abort.get(option)
/** Creates an effect from a Maybe[A] and handles Absent to Abort[Absent].
*
* @param maybe
* The Maybe[A] to create an effect from
* @return
* An effect that attempts to run the given effect and handles Absent to Abort[Absent].
*/
def fromMaybe[A](maybe: Maybe[A])(using Frame): A < Abort[Absent] =
Abort.get(maybe)
/** Creates an effect from a Result[E, A] and handles Result.Failure[E] to Abort[E].
*
* @param result
* The Result[E, A] to create an effect from
* @return
* An effect that attempts to run the given effect and handles Result.Failure[E] to Abort[E].
*/
def fromResult[E, A](result: Result[E, A])(using Frame): A < Abort[E] =
Abort.get(result)
/** Creates an effect from a Future[A] and handles the Future to Async.
*
* @param future
* The Future[A] to create an effect from
* @return
* An effect that attempts to run the given effect and handles the Future to Async.
*/
def fromFuture[A: Flat](future: => Future[A])(using Frame): A < (Async & Abort[Throwable]) =
Async.fromFuture(future)
/** Creates an effect from a Promise[A] and handles the Promise to Async.
*
* @param promise
* The Promise[A] to create an effect from
* @return
* An effect that attempts to run the given effect and handles the Promise to Async.
*/
def fromPromiseScala[A: Flat](promise: => scala.concurrent.Promise[A])(using Frame): A < (Async & Abort[Throwable]) =
fromFuture(promise.future)
/** Creates an effect from a sequence and handles the sequence to Choice.
*
* @param sequence
* The sequence to create an effect from
* @return
* An effect that attempts to run the given effect and handles the sequence to Choice.
*/
def fromSeq[A](sequence: Seq[A])(using Frame): A < Choice =
Choice.get(sequence)
/** Creates an effect from a Try[A] and handles the Try to Abort[Throwable].
*
* @param _try
* The Try[A] to create an effect from
* @return
* An effect that attempts to run the given effect and handles the Try to Abort[Throwable].
*/
def fromTry[A](_try: scala.util.Try[A])(using Frame): A < Abort[Throwable] =
Abort.get(_try)
/** Logs an informational message to the console.
*
* @param message
* The message to log
* @return
* An effect that logs the message to the console
*/
inline def logInfo(inline message: => String): Unit < IO =
Log.info(message)
/** Logs an informational message to the console with an error.
*
* @param message
* The message to log
* @param err
* The error to log
* @return
* An effect that logs the message and error to the console
*/
inline def logInfo(inline message: => String, inline err: => Throwable): Unit < IO =
Log.info(message, err)
/** Logs a warning message to the console.
*
* @param message
* The message to log
* @return
* An effect that logs the message to the console
*/
inline def logWarn(inline message: => String): Unit < IO =
Log.warn(message)
/** Logs a warning message to the console with an error.
*
* @param message
* The message to log
* @param err
* The error to log
* @return
* An effect that logs the message and error to the console
*/
inline def logWarn[S, S1](inline message: => String, inline err: => Throwable): Unit < IO =
Log.warn(message, err)
/** Logs a debug message to the console.
*
* @param message
* The message to log
* @return
* An effect that logs the message to the console
*/
inline def logDebug(inline message: => String): Unit < IO =
Log.debug(message)
/** Logs a debug message to the console with an error.
*
* @param message
* The message to log
* @param err
* The error to log
* @return
* An effect that logs the message and error to the console
*/
inline def logDebug(inline message: => String, inline err: => Throwable): Unit < IO =
Log.debug(message, err)
/** Logs an error message to the console.
*
* @param message
* The message to log
* @return
* An effect that logs the message to the console
*/
inline def logError(inline message: => String): Unit < IO =
Log.error(message)
/** Logs an error message to the console with an error.
*
* @param message
* The message to log
* @param err
* The error to log
* @return
* An effect that logs the message and error to the console
*/
inline def logError(inline message: => String, inline err: => Throwable): Unit < IO =
Log.error(message, err)
/** Logs a trace message to the console.
*
* @param message
* The message to log
* @return
* An effect that logs the message to the console
*/
inline def logTrace(inline message: => String): Unit < IO =
Log.trace(message)
/** Logs a trace message to the console with an error.
*
* @param message
* The message to log
* @param err
* The error to log
* @return
* An effect that logs the message and error to the console
*/
inline def logTrace(inline message: => String, inline err: Throwable): Unit < IO =
Log.trace(message, err)
/** Creates an effect that never completes using Async.
*
* @return
* An effect that never completes
*/
def never(using Frame): Nothing < Async =
Fiber.never.join
*> IO(throw new IllegalStateException("Async.never completed"))
/** Provides a dependency to an effect using Env.
*
* @param dependency
* The dependency to provide
* @param effect
* The effect to provide the dependency to
* @return
* An effect that provides the dependency to the effect
*/
def provideFor[E, A, SA, ER](dependency: E)(effect: A < (SA & Env[E | ER]))(
using
reduce: Reducible[Env[ER]],
t: Tag[E],
fl: Flat[A],
frame: Frame
): A < (SA & reduce.SReduced) =
Env.run(dependency)(effect)
/** Creates a scoped effect using Resource.
*
* @param resource
* The resource to create a scoped effect from
* @return
* An effect that manages the resource lifecycle using Resource and IO effects
*/
def scoped[A, S](resource: => A < (S & Resource))(using Frame): A < (Async & S) =
Resource.run(resource)
/** Retrieves a dependency from Env.
*
* @return
* An effect that retrieves the dependency from Env
*/
def service[D](using Tag[D], Frame): D < Env[D] =
Env.get[D]
/** Retrieves a dependency from Env and applies a function to it.
*
* @param fn
* The function to apply to the dependency
* @return
* An effect that retrieves the dependency from Env and applies the function to it
*/
def serviceWith[D](using Tag[D], Frame): [A, S] => (D => A < S) => A < (S & Env[D]) =
[A, S] => (fn: D => (A < S)) => service[D].map(d => fn(d))
/** Sleeps for a given duration using Async.
*
* @param duration
* The duration to sleep for
* @return
* An effect that sleeps for the given duration
*/
def sleep(duration: Duration)(using Frame): Unit < Async =
Async.sleep(duration)
/** Suspends an effect using IO.
*
* @param effect
* The effect to suspend
* @return
* An effect that suspends the given effect
*/
def suspend[A, S](effect: => A < S)(using Frame): A < (S & IO) =
IO(effect)
/** Suspends an effect using IO and handles any exceptions that occur to Abort[Throwable].
*
* @param effect
* The effect to suspend
* @return
* An effect that suspends the given effect and handles any exceptions that occur to Abort[Throwable]
*/
def suspendAttempt[A, S](effect: => A < S)(using
Flat[A],
Frame
): A < (S & IO & Abort[Throwable]) =
IO(Abort.catching[Throwable](effect))
/** Traverses a sequence of effects and collects the results.
*
* @param sequence
* The sequence of effects to traverse
* @return
* An effect that traverses the sequence of effects and collects the results
*/
def traverse[A, S](sequence: Seq[A < S])(using Frame): Seq[A] < S =
Kyo.collect(sequence)
/** Traverses a sequence of effects and discards the results.
*
* @param sequence
* The sequence of effects to traverse
* @return
* An effect that traverses the sequence of effects and discards the results
*/
def traverseDiscard[A, S](sequence: Seq[A < S])(using Frame): Unit < S =
Kyo.collectDiscard(sequence)
/** Traverses a sequence of effects in parallel and collects the results.
*
* @param sequence
* The sequence of effects to traverse in parallel
* @return
* An effect that traverses the sequence of effects in parallel and collects the results
*/
def traversePar[A](
sequence: => Seq[A < Async]
)(using Flat[A], Frame): Seq[A] < Async =
foreachPar(sequence)(identity)
/** Traverses a sequence of effects in parallel and discards the results.
*
* @param sequence
* The sequence of effects to traverse in parallel
* @return
* An effect that traverses the sequence of effects in parallel and discards the results
*/
def traverseParDiscard[A](
sequence: => Seq[A < Async]
)(using Flat[A], Frame): Unit < Async =
foreachPar(sequence)(identity).unit
end extension