mirror of https://github.com/sbt/sbt.git
47 lines
1.2 KiB
Scala
47 lines
1.2 KiB
Scala
package coursier.util
|
|
|
|
import scala.concurrent.{ExecutionContext, Future, Promise}
|
|
|
|
final case class Task[T](value: ExecutionContext => Future[T]) extends AnyVal {
|
|
|
|
def map[U](f: T => U): Task[U] =
|
|
Task(implicit ec => value(ec).map(f))
|
|
def flatMap[U](f: T => Task[U]): Task[U] =
|
|
Task(implicit ec => value(ec).flatMap(t => f(t).value(ec)))
|
|
|
|
def handle[U >: T](f: PartialFunction[Throwable, U]): Task[U] =
|
|
Task(ec => value(ec).recover(f)(ec))
|
|
|
|
def future()(implicit ec: ExecutionContext): Future[T] =
|
|
value(ec)
|
|
}
|
|
|
|
object Task extends PlatformTask {
|
|
|
|
def point[A](a: A): Task[A] = {
|
|
val future = Future.successful(a)
|
|
Task(_ => future)
|
|
}
|
|
|
|
def delay[A](a: => A): Task[A] =
|
|
Task(ec => Future(a)(ec))
|
|
|
|
def never[A]: Task[A] =
|
|
Task(_ => Promise[A].future)
|
|
|
|
def tailRecM[A, B](a: A)(fn: A => Task[Either[A, B]]): Task[B] =
|
|
Task[B] { implicit ec =>
|
|
def loop(a: A): Future[B] =
|
|
fn(a).future().flatMap {
|
|
case Right(b) =>
|
|
Future.successful(b)
|
|
case Left(a) =>
|
|
// this is safe because recursive
|
|
// flatMap is safe on Future
|
|
loop(a)
|
|
}
|
|
loop(a)
|
|
}
|
|
}
|
|
|