membership-attribute-service/app/services/subscription/Sequence.scala (16 lines of code) (raw):
package services.subscription
import scalaz.{-\/, NonEmptyList, \/, \/-}
/*
Sequence turns a list of either into an either of list. In this case, it does it by putting all the rights into a list and returning
that as a right. However if there are no rights, it will return a left of any lefts.
This is mostly useful if we want to try a load of things and hopefully one will succeed. It's not too good in case things
go wrong, we don't know which ones should have failed and which shouldn't have. But at least it keeps most of the errors.
*/
object Sequence {
def apply[A](eitherList: List[String \/ A]): String \/ NonEmptyList[A] = {
val zero = (List[String](), List[A]())
val product = eitherList.foldRight(zero)({
case (-\/(left), (accuLeft, accuRight)) => (left :: accuLeft, accuRight)
case (\/-(right), (accuLeft, accuRight)) => (accuLeft, right :: accuRight)
})
// if any are right, return them all, otherwise return all the left
product match {
case (Nil, Nil) => -\/("no subscriptions found at all, even invalid ones") // no failures or successes
case (errors, Nil) => -\/(errors.mkString("\n")) // no successes
case (_, result :: results) => \/-(NonEmptyList.fromSeq(result, results)) // discard some errors as long as some worked (log it?)
}
}
}