Skip to content

Commit

Permalink
Merge pull request #1525 from lift/msf_issue_1525
Browse files Browse the repository at this point in the history
Implement a helper for Iterator[Box[T]] => Box[List[T]]
  • Loading branch information
Shadowfiend committed Apr 8, 2014
2 parents 3387cdd + 1d2cf14 commit 6ca7a38
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
39 changes: 38 additions & 1 deletion core/common/src/main/scala/net/liftweb/common/Box.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,41 @@ import scala.reflect.Manifest

import java.util.{Iterator => JavaIterator, ArrayList => JavaArrayList}

/**
* Helper class to provide an easy way for converting Lists of Boxes[T] into
* a Box of List[T].
**/
case class ListOfBoxes[T](theListOfBoxes: List[Box[T]]) {
/**
* Convert a List of Boxes into a single Box containting a List[T], where T is
* the parameterized type of the Boxes.
*
* This method is useful for those cases where you have a lot of operations being
* executed that all return some Box[T]. You want just a List[T] if all of those
* operations succeeded, but you don't want to have Failures disappear if any were
* present in the list.
*
* If all of the Boxes in the List are Full or Empty, we return a Full box containing
* a List of all of the Full Box values that were present. If any of the Boxes contain
* a Failure, a ParamFailure is returned, containing the original List[Box[T]] as the
* param.
*
* It is worth noting that the size of the list in the resulting Box[List[T]] may not be equal
* to the size of the List[Box[T]] that is fed as Empty values will disappear altogether in the
* conversion.
*
* @param failureErrorMessage The string that should be placed in the message for the Failure.
* @return A Full[List[T]] if no Failures were present. ParamFailure[List[Box[T]]] otherwise.
**/
def toSingleBox(failureErrorMessage: String): Box[List[T]] = {
if (theListOfBoxes.exists(_.isInstanceOf[Failure])) {
Failure(failureErrorMessage) ~> theListOfBoxes
} else {
Full(theListOfBoxes.flatten)
}
}
}

/**
* The bridge from Java to Scala Box
*/
Expand All @@ -46,7 +81,9 @@ class BoxJBridge {
*
* It also provides implicit methods to transform Option to Box, Box to Iterable, and Box to Option
*/
object Box extends BoxTrait
object Box extends BoxTrait {
implicit def listToListOfBoxes[T](boxes: List[Box[T]]) = ListOfBoxes(boxes)
}

/**
* The Box companion object provides methods to create a Box from:
Expand Down
23 changes: 23 additions & 0 deletions core/common/src/test/scala/net/liftweb/common/BoxSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,29 @@ class BoxSpec extends Specification with ScalaCheck with BoxGenerator {
}
}

"A List[Box[T]]" should {
"be convertable to a Box[List[T]] when all are Full" in {
val someBoxes: List[Box[String]] = List(Full("bacon"), Full("sammich"))
val singleBox = someBoxes.toSingleBox("Box failed!")

singleBox must_== Full(List("bacon", "sammich"))
}

"be convertable to a Box[List[T]] when some are Full and some are Empty" in {
val someBoxes: List[Box[String]] = List(Full("bacon"), Full("sammich"), Empty)
val singleBox = someBoxes.toSingleBox("Box failed!")

singleBox must_== Full(List("bacon", "sammich"))
}

"be convertable to a ParamFailure[Box[List[T]]] when any are Failure" in {
val someBoxes: List[Box[String]] = List(Full("bacon"), Full("sammich"), Failure("I HATE BACON"))
val singleBox = someBoxes.toSingleBox("This should be in the param failure.")

singleBox must_== ParamFailure("This should be in the param failure.", None, None, someBoxes)
}
}

}


Expand Down

0 comments on commit 6ca7a38

Please sign in to comment.