Skip to content

Commit

Permalink
Merge pull request #534 from cchantep/feature/reads-flatmapresult
Browse files Browse the repository at this point in the history
Add Reads.flatMapResult
  • Loading branch information
ignasi35 authored Nov 3, 2020
2 parents 14298e9 + 4260b95 commit 31ddbe3
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
25 changes: 25 additions & 0 deletions play-json/shared/src/main/scala/play/api/libs/json/Reads.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,31 @@ trait Reads[A] { self =>
this.reads(json)
}

/**
* Creates a new `Reads`, which transforms the successful result
* from the current instance using the given function.
*
* @param f the function applied on the successful `A` value
*
* {{{
* final class Foo private(val code: String) extends AnyVal
*
* val A = new Foo("A")
* val B = new Foo("B")
*
* import play.api.libs.json.Reads
*
* val r: Reads[Foo] = implicitly[Reads[String]].flatMapResult {
* case "A" => JsSuccess(A)
* case "B" => JsSuccess(B)
* case _ => JsError("error.expected.foo")
* }
* }}}
*/
def flatMapResult[B](f: A => JsResult[B]): Reads[B] = Reads[B] {
this.reads(_).flatMap(f)
}

def andThen[B](rb: Reads[B])(implicit witness: A <:< JsValue): Reads[B] =
rb.composeWith(this.map(witness))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,23 @@ final class ReadsSharedSpec extends AnyWordSpec with Matchers with Inside {
}
}

"Reads result" should {
"be flat-mapped" in {
val readsArrayAsOwner: Reads[Owner] =
Reads.seq[String].flatMapResult {
case login +: avatar +: url +: _ =>
JsSuccess(Owner(login, avatar, url))

case _ =>
JsError("error.expected.owner-as-jsarray")
}

readsArrayAsOwner.reads(JsArray(Seq(JsString("foo"), JsString("bar"), JsString("url://owner")))) mustEqual JsSuccess(
Owner("foo", "bar", "url://owner")
)
}
}

"Functional Reads" should {
import play.api.libs.functional.syntax._

Expand Down

0 comments on commit 31ddbe3

Please sign in to comment.