Skip to content

Commit

Permalink
feat: implement interop for newtype
Browse files Browse the repository at this point in the history
  • Loading branch information
GrigoriiBerezin committed May 10, 2024
1 parent 61b7634 commit 108af08
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
19 changes: 19 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ lazy val zioJsonRoot = project
zioJsonInteropScalaz7x.js,
zioJsonInteropScalaz7x.jvm,
zioJsonInteropScalaz7x.native,
zioJsonInteropNewtype.js,
zioJsonInteropNewtype.jvm,
zioJsonGolden
)

Expand Down Expand Up @@ -357,6 +359,22 @@ lazy val zioJsonInteropRefined = crossProject(JSPlatform, JVMPlatform, NativePla
)
.enablePlugins(BuildInfoPlugin)

lazy val zioJsonInteropNewtype = crossProject(JSPlatform, JVMPlatform)
.in(file("zio-json-interop-newtype"))
.dependsOn(zioJson)
.settings(stdSettings("zio-json-interop-newtype"))
.settings(buildInfoSettings("zio.json.interop.newtype"))
.settings(macroExpansionSettings)
.settings(
libraryDependencies ++= Seq(
"io.estatico" %%% "newtype" % "0.4.4",
"dev.zio" %%% "zio-test" % zioVersion % "test",
"dev.zio" %%% "zio-test-sbt" % zioVersion % "test"
),
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
)
.enablePlugins(BuildInfoPlugin)

lazy val zioJsonInteropScalaz7x = crossProject(JSPlatform, JVMPlatform, NativePlatform)
.in(file("zio-json-interop-scalaz7x"))
.dependsOn(zioJson)
Expand Down Expand Up @@ -398,6 +416,7 @@ lazy val docs = project
zioJsonInteropHttp4s,
zioJsonInteropRefined.jvm,
zioJsonInteropScalaz7x.jvm,
zioJsonInteropNewtype.jvm,
zioJsonGolden
),
readmeAcknowledgement :=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package zio.json.interop

import io.estatico.newtype.Coercible
import io.estatico.newtype.ops._
import zio.json.{ JsonDecoder, JsonEncoder, JsonFieldDecoder, JsonFieldEncoder }

package object newtype {
implicit def coercibleDecoder[A: Coercible[B, *], B: JsonDecoder]: JsonDecoder[A] =
JsonDecoder[B].map(_.coerce[A])

implicit def coercibleEncoder[A: Coercible[*, B], B: JsonEncoder]: JsonEncoder[A] =
JsonEncoder[B].contramap(_.coerce[B])

implicit def coercibleKeyDecoder[A: Coercible[B, *], B: JsonFieldDecoder]: JsonFieldDecoder[A] =
JsonFieldDecoder[B].map(_.coerce[A])

implicit def coercibleKeyEncoder[A: Coercible[*, B], B: JsonFieldEncoder]: JsonFieldEncoder[A] =
JsonFieldEncoder[B].contramap(_.coerce[B])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package zio.json.interop.newtype

import io.estatico.newtype.macros.newtype
import zio.json.{ DecoderOps, DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder }
import zio.test.Assertion.{ equalTo, isRight }
import zio.test.{ Spec, ZIOSpecDefault, assert, assertTrue }

object NewtypeSpec extends ZIOSpecDefault {
override def spec: Spec[Environment, Any] = suite("newtype")(
test("newtype") {
assert("""{"name":"fommil"}""".fromJson[Person])(isRight(equalTo(Person(Name("fommil"))))) &&
assertTrue(Person(Name("fommil")).toJson == """{"name":"fommil"}""")
}
)

@newtype case class Name(value: String)
case class Person(name: Name)
object Person {
implicit val encoder: JsonEncoder[Person] = DeriveJsonEncoder.gen[Person]
implicit val decoder: JsonDecoder[Person] = DeriveJsonDecoder.gen[Person]
}
}

0 comments on commit 108af08

Please sign in to comment.