/* sbt -- Simple Build Tool
 * Copyright 2010 Mark Harrah
 */
package sbt

// used instead of Either[Incomplete, T] for type inference

/** Result of completely evaluating a task.*/
sealed trait Result[+T]
{
	def toEither: Either[Incomplete, T]
}
/** Indicates the task did not complete normally and so it does not have a value.*/
final case class Inc(cause: Incomplete) extends Result[Nothing]
{
	def toEither: Either[Incomplete, Nothing] = Left(cause)
}
/** Indicates the task completed normally and produced the given `value`.*/
final case class Value[+T](value: T) extends Result[T]
{
	def toEither: Either[Incomplete, T] = Right(value)
}

object Result
{
	type Id[X] = X
	val tryValue = new (Result ~> Id) {
		def apply[T](r: Result[T]): T =
			r match {
				case Value(v) => v
				case Inc(i) => throw i
			}
	}
	def tryValues[S](r: Seq[Result[Unit]], v: Result[S]): S =
	{
		r foreach tryValue[Unit]
		tryValue[S](v)
	}
	implicit def fromEither[T](e: Either[Incomplete, T]): Result[T] = e match {
		case Left(i) => Inc(i)
		case Right(v) => Value(v)
	}
}