Skip to content

Commit 38b8449

Browse files
author
Matteo Di Pirro
committed
SCALA-400 Add code for zio-json article
1 parent 1f5cebd commit 38b8449

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,10 @@ lazy val zio2 = (project in file("zio-2"))
640640
name := "zio-2",
641641
scalaVersion := scala3Version,
642642
libraryDependencies += "dev.zio" %% "zio" % zioVersion,
643+
libraryDependencies += "dev.zio" %% "zio-json" % "0.6.2",
643644
libraryDependencies += "dev.zio" %% "zio-test" % zioVersion % Test,
644645
libraryDependencies += "dev.zio" %% "zio-test-sbt" % zioVersion % Test,
646+
libraryDependencies ++= scalaTestDeps,
645647
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
646648
)
647649

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.baeldung.scala.zio.json
2+
3+
import zio.json.*
4+
5+
sealed trait Command
6+
case class Start(timeout: Long) extends Command
7+
case object Stop extends Command
8+
9+
@jsonDiscriminator("type")
10+
sealed trait Command2
11+
case class Start2(timeout: Long) extends Command2
12+
case object Stop2 extends Command2
13+
14+
object Start {
15+
implicit val encoder: JsonEncoder[Start] = DeriveJsonEncoder.gen[Start]
16+
implicit val decoder: JsonDecoder[Start] = DeriveJsonDecoder.gen[Start]
17+
}
18+
19+
object Command {
20+
implicit val encoder: JsonEncoder[Command] = DeriveJsonEncoder.gen[Command]
21+
implicit val decoder: JsonDecoder[Command] = DeriveJsonDecoder.gen[Command]
22+
}
23+
24+
object Command2 {
25+
implicit val encoder: JsonEncoder[Command2] = DeriveJsonEncoder.gen[Command2]
26+
implicit val decoder: JsonDecoder[Command2] = DeriveJsonDecoder.gen[Command2]
27+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.baeldung.scala.zio.json
2+
3+
import org.scalatest.matchers.should.Matchers
4+
import org.scalatest.wordspec.AnyWordSpec
5+
import zio.json.*
6+
7+
class DecodingSpec extends AnyWordSpec with Matchers {
8+
"zio-json" should {
9+
"decode a JSON object to a case class" in {
10+
"""{"timeout":789}""".fromJson[Start] shouldBe Right(Start(789))
11+
}
12+
13+
"return a decoding error if the JSON is not correct" in {
14+
"""{"duration":789}""".fromJson[Start] shouldBe Left(".timeout(missing)")
15+
}
16+
17+
"decode a JSON object with extra fields to a case class" in {
18+
"""{"timeout":789, "extra": "field"}""".fromJson[Start] shouldBe Right(
19+
Start(789)
20+
)
21+
}
22+
23+
"decode an ADT to JSON" in {
24+
"""{"Start":{"timeout":100}}""".fromJson[Command] shouldBe Right(
25+
Start(100)
26+
)
27+
"""{"Stop":{}}""".fromJson[Command] shouldBe Right(Stop)
28+
}
29+
30+
"decode Stop to JSON" in {
31+
implicit val decoder: JsonDecoder[Stop.type] =
32+
implicitly[JsonDecoder[String]].map(_ => Stop)
33+
34+
"""{"Start":{"timeout":100}}""".fromJson[Command] shouldBe Right(
35+
Start(100)
36+
)
37+
""""Stop"""".fromJson[Stop.type] shouldBe Right(Stop)
38+
}
39+
40+
"use a discriminator" in {
41+
"""{"type":"Start2","timeout":100}""".fromJson[Command2] shouldBe Right(
42+
Start2(100)
43+
)
44+
"""{"type":"Stop2"}""".fromJson[Command2] shouldBe Right(Stop2)
45+
}
46+
47+
"fail if there's no discriminator" in {
48+
"""{"timeout":100}""".fromJson[Command2] shouldBe Left(
49+
"(missing hint 'type')"
50+
)
51+
}
52+
}
53+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.baeldung.scala.zio.json
2+
3+
import org.scalatest.matchers.should.Matchers
4+
import org.scalatest.wordspec.AnyWordSpec
5+
import zio.json.*
6+
7+
class EncodingSpec extends AnyWordSpec with Matchers {
8+
"zio-json" should {
9+
"encode a case class to JSON" in {
10+
Start(100).toJson shouldBe """{"timeout":100}"""
11+
}
12+
13+
"encode an ADT to JSON" in {
14+
(Start(100): Command).toJson shouldBe """{"Start":{"timeout":100}}"""
15+
(Stop: Command).toJson shouldBe """{"Stop":{}}"""
16+
}
17+
18+
"encode Stop to JSON" in {
19+
implicit val encoder: JsonEncoder[Stop.type] =
20+
implicitly[JsonEncoder[String]].contramap(_.toString())
21+
22+
(Start(100): Command).toJson shouldBe """{"Start":{"timeout":100}}"""
23+
Stop.toJson shouldBe """"Stop""""
24+
}
25+
26+
"use a discriminator" in {
27+
(Start2(
28+
100
29+
): Command2).toJson shouldBe """{"type":"Start2","timeout":100}"""
30+
(Stop2: Command2).toJson shouldBe """{"type":"Stop2"}"""
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)