Skip to content

Commit daab19f

Browse files
committed
Add recursive methods
1 parent 70c1d00 commit daab19f

14 files changed

Lines changed: 339 additions & 5 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
trait RecursiveFormat { self: Format.type =>
8+
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
trait RecursiveOFormat { self: OFormat.type =>
8+
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
trait RecursiveOWrites { self: OWrites.type =>
8+
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
trait RecursiveReads { self: Reads.type =>
8+
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
trait RecursiveWrites { self: Writes.type =>
8+
9+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
import scala.annotation.tailrec
8+
9+
trait RecursiveFormat { self: Format.type =>
10+
final def recursive[A](f: Format[A] ?=> Format[A]): Format[A] = {
11+
lazy val res: Format[A] = f(using RecursiveFormat.DeferredFormat(() => res))
12+
res
13+
}
14+
}
15+
16+
private[json] object RecursiveFormat {
17+
private final case class DeferredFormat[A](value: () => Format[A]) extends Format[A] {
18+
private lazy val resolved: Format[A] = resolve(value)
19+
20+
@tailrec
21+
private def resolve(f: () => Format[A]): Format[A] =
22+
f() match {
23+
case DeferredFormat(f) =>
24+
resolve(f)
25+
case next =>
26+
next
27+
}
28+
29+
override def reads(json: JsValue): JsResult[A] =
30+
resolved.reads(json)
31+
32+
override def writes(o: A): JsValue =
33+
resolved.writes(o)
34+
}
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
import scala.annotation.tailrec
8+
9+
trait RecursiveOFormat { self: OFormat.type =>
10+
final def recursive[A](f: OFormat[A] ?=> OFormat[A]): OFormat[A] = {
11+
lazy val res: OFormat[A] = f(using RecursiveOFormat.DeferredOFormat(() => res))
12+
res
13+
}
14+
}
15+
16+
private[json] object RecursiveOFormat {
17+
private final case class DeferredOFormat[A](value: () => OFormat[A]) extends OFormat[A] {
18+
private lazy val resolved: OFormat[A] = resolve(value)
19+
20+
@tailrec
21+
private def resolve(f: () => OFormat[A]): OFormat[A] =
22+
f() match {
23+
case DeferredOFormat(f) =>
24+
resolve(f)
25+
case next =>
26+
next
27+
}
28+
29+
override def reads(json: JsValue): JsResult[A] =
30+
resolved.reads(json)
31+
32+
override def writes(o: A): JsObject =
33+
resolved.writes(o)
34+
}
35+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
import scala.annotation.tailrec
8+
9+
trait RecursiveOWrites { self: OWrites.type =>
10+
final def recursive[A](f: OWrites[A] ?=> OWrites[A]): OWrites[A] = {
11+
lazy val res: OWrites[A] = f(using RecursiveOWrites.DeferredOWrites(() => res))
12+
res
13+
}
14+
}
15+
16+
private[json] object RecursiveOWrites {
17+
private final case class DeferredOWrites[A](value: () => OWrites[A]) extends OWrites[A] {
18+
private lazy val resolved: OWrites[A] = resolve(value)
19+
20+
@tailrec
21+
private def resolve(f: () => OWrites[A]): OWrites[A] =
22+
f() match {
23+
case DeferredOWrites(f) =>
24+
resolve(f)
25+
case next =>
26+
next
27+
}
28+
29+
override def writes(o: A): JsObject =
30+
resolved.writes(o)
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
import scala.annotation.tailrec
8+
9+
trait RecursiveReads { self: Reads.type =>
10+
final def recursive[A](f: Reads[A] ?=> Reads[A]): Reads[A] = {
11+
lazy val res: Reads[A] = f(using RecursiveReads.DeferredReads(() => res))
12+
res
13+
}
14+
}
15+
16+
private[json] object RecursiveReads {
17+
private final case class DeferredReads[A](value: () => Reads[A]) extends Reads[A] {
18+
private lazy val resolved: Reads[A] = resolve(value)
19+
20+
@tailrec
21+
private def resolve(f: () => Reads[A]): Reads[A] =
22+
f() match {
23+
case DeferredReads(f) =>
24+
resolve(f)
25+
case next =>
26+
next
27+
}
28+
29+
override def reads(json: JsValue): JsResult[A] =
30+
resolved.reads(json)
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
3+
*/
4+
5+
package play.api.libs.json
6+
7+
import scala.annotation.tailrec
8+
9+
trait RecursiveWrites { self: Writes.type =>
10+
final def recursive[A](f: Writes[A] ?=> Writes[A]): Writes[A] = {
11+
lazy val res: Writes[A] = f(using RecursiveWrites.DeferredWrites(() => res))
12+
res
13+
}
14+
}
15+
16+
private[json] object RecursiveWrites {
17+
private final case class DeferredWrites[A](value: () => Writes[A]) extends Writes[A] {
18+
private lazy val resolved: Writes[A] = resolve(value)
19+
20+
@tailrec
21+
private def resolve(f: () => Writes[A]): Writes[A] =
22+
f() match {
23+
case DeferredWrites(f) =>
24+
resolve(f)
25+
case next =>
26+
next
27+
}
28+
29+
override def writes(o: A): JsValue =
30+
resolved.writes(o)
31+
}
32+
}

0 commit comments

Comments
 (0)