Skip to content

Commit

Permalink
Add zio-json and zio-schema integrations
Browse files Browse the repository at this point in the history
  • Loading branch information
little-inferno committed May 13, 2024
1 parent bd4d300 commit c49b086
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 1 deletion.
20 changes: 20 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ lazy val derevo = project
tethys,
tethysMagnolia,
sangria,
zioJson,
zioSchema,
tests,
)

Expand Down Expand Up @@ -164,6 +166,24 @@ lazy val sangria =
)
.dependsOn(core)

lazy val zioJson =
(project in file("modules/zioJson"))
.settings(publishSettings)
.settings(
name := "derevo-zio-json",
libraryDependencies ++= Seq(Dependencies.zioJson),
)
.dependsOn(core)

lazy val zioSchema =
(project in file("modules/zioSchema"))
.settings(publishSettings)
.settings(
name := "derevo-zio-schema",
libraryDependencies ++= Seq(Dependencies.zioSchema, Dependencies.zioSchemaDerivation),
)
.dependsOn(core)

lazy val tests =
(project in file("modules/tests"))
.settings(noPublishSettings)
Expand Down
14 changes: 14 additions & 0 deletions modules/zioJson/src/main/scala/derevo/zio/json/zio.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package derevo.zio.json

import derevo.{Derevo, Derivation, NewTypeDerivation, delegating}
import zio.json._

@delegating("zio.json.DeriveJsonDecoder.gen")
object jsonDecoder extends Derivation[JsonDecoder] with NewTypeDerivation[JsonDecoder] {
def instance[A]: JsonDecoder[A] = macro Derevo.delegate[JsonDecoder, A]
}

@delegating("zio.json.DeriveJsonEncoder.gen")
object jsonEncoder extends Derivation[JsonEncoder] with NewTypeDerivation[JsonEncoder] {
def instance[A]: JsonEncoder[A] = macro Derevo.delegate[JsonEncoder, A]
}
50 changes: 50 additions & 0 deletions modules/zioJson/src/test/scala/derevo/zio/json/ZioJsonSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package derevo.zio.json

import derevo.derive
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import zio.json.JsonCodecConfiguration.SumTypeHandling
import zio.json._

@derive(jsonEncoder)
sealed trait Choice

object Choice {
implicit val Configuration: JsonCodecConfiguration =
JsonCodecConfiguration(SumTypeHandling.DiscriminatorField("type"))
}

@derive(jsonEncoder)
final case class First(a: Int, b: String) extends Choice

@derive(jsonEncoder)
final case class Second(c: Boolean, f: Option[Foo]) extends Choice

@derive(jsonEncoder)
final case class P[A, B](a: A, b: List[B])

@derive(jsonEncoder, jsonDecoder)
case class Foo(d: Int, e: String)

@derive(jsonEncoder)
case class ChoiceList(list: List[Choice], amount: Int)

class ZioJsonSpec extends AnyFlatSpec with Matchers {
"Encoder derivation for ADT" should "work correctly" in {
val choices = ChoiceList(List(First(1, "lol"), Second(c = true, Some(Foo(1, "kek")))), 2)

choices.toJson shouldBe """{"list":[{"type":"First","a":1,"b":"lol"},{"type":"Second","c":true,"f":{"d":1,"e":"kek"}}],"amount":2}"""
}

"Decoder derivation for case class" should "work correctly" in {
val foo = Foo(100, "kek")

"""{"d":100,"e":"kek"}""".fromJson[Foo] shouldBe Right(foo)
}

"Parametric derivation for case class" should "work correctly" in {
val p = P(123.0, List(1, 2, 3))

p.toJson shouldBe """{"a":123.0,"b":[1,2,3]}"""
}
}
9 changes: 9 additions & 0 deletions modules/zioSchema/src/main/scala/derevo/zio/schema/zio.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package derevo.zio.schema

import derevo.{Derevo, Derivation, NewTypeDerivation, delegating}
import zio.schema.Schema

@delegating("zio.schema.DeriveSchema.gen")
object schema extends Derivation[Schema] with NewTypeDerivation[Schema] {
def instance[A]: Schema[A] = macro Derevo.delegate[Schema, A]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package derevo.zio.json

import derevo.derive
import derevo.zio.schema.schema
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import zio.schema._

@derive(schema)
final case class Person(name: String, age: Int)

class ZioSchemaSpec extends AnyFlatSpec with Matchers {
"Schema derivation" should "work correctly" in {
val person1 = Person("Gabriel", 45)
val person2 = Person("Gabi", 54)

val patch: Patch[Person] = Schema[Person].diff(person1, person2)
val inverted: Patch[Person] = patch.invert

val result1: Either[String, Person] = patch.patch(person1)
val result2: Either[String, Person] = result1.flatMap(inverted.patch)

result2 shouldBe Right(person1)
}
}
8 changes: 8 additions & 0 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ object Dependencies {
val macroParadise = "2.1.1"

val sangria = "3.2.0"

val zioJson = "0.6.2"

val zioSchema = "1.1.1"
}

lazy val magnolia = "com.propensive" %% "magnolia" % Version.magnolia
Expand All @@ -66,6 +70,10 @@ object Dependencies {
lazy val estatico = "io.estatico" %% "newtype" % Version.estatico
lazy val supertagged = "org.rudogma" %% "supertagged" % Version.supertagged

lazy val zioSchema = "dev.zio" %% "zio-schema" % Version.zioSchema
lazy val zioSchemaDerivation = "dev.zio" %% "zio-schema-derivation" % Version.zioSchema
lazy val zioJson = "dev.zio" %% "zio-json" % Version.zioJson

lazy val macroParadise = "org.scalamacros" % "paradise" % Version.macroParadise cross CrossVersion.patch
lazy val kindProjector = "org.typelevel" %% "kind-projector" % Version.kindProjector cross CrossVersion.patch

Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.7.1
sbt.version=1.9.9

0 comments on commit c49b086

Please sign in to comment.