This is a Json codec implementation for E
and EOr
types based on play-json. It provides play-json's Reads
and Writes
as well as e's own Codec
(see e-scala docs).
If you use SBT, add following to your build.sbt
:
libraryDependencies += "dev.akif" %% "e-play-json" % "3.0.1"
If you use Maven, add following to your pom.xml
:
<dependencies>
<dependency>
<groupId>dev.akif</groupId>
<artifactId>e-play-json_3</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
If you use Gradle, add following to your project's build.gradle
:
dependencies {
implementation('dev.akif:e-play-json_3:3.0.1')
}
Below are some details and examples of e-play-json's content. For more, please check corresponding automated tests and e-play-json's documentation.
To get started, add following import which will cover all your needs:
import e.playjson.{*, given}
e-play-json provides implicit definitions so that regular play-json reading can be done. However, it also provides e's own Codec. Using this is convenient as it reports decoding failures as E errors.
import e.playjson.{*, given}
import play.api.libs.json.*
decode[String](Json.toJson(123))
decode[String](Json.toJson("test"))
case class Foo(bar: Boolean)
given fooReads: Reads[Foo] = Json.reads[Foo]
given fooWrites: Writes[Foo] = Json.writes[Foo]
decode[Foo](Json.obj())
decode[Foo](Json.toJson(Foo(false)))
Reading a Json as E yields EOr[E]
whose error is the decoding failure. If the decoding succeeds, the provided value is the decoded E.
import e.playjson.{*, given}
import e.scala.E
import play.api.libs.json.*
// Decodes as `E.empty`
decode[E](Json.obj())
// Decoding failure, also an E
decode[E](Json.arr())
val decoder = makeDecoder[E]
decoder.decode(Json.obj("code" -> 1, "name" -> "test"))
e-play-json provides implicit definitions so that regular play-json writing can be done. It also provides e's own Codec and encoding can be done with it too.
import e.playjson.{*, given}
import e.scala.E
encode(E.empty)
encode(E.name("test").message("Test").cause(E.code(1)))
val encoder = makeEncoder[E]
encoder.encode(E.code(2))
import e.playjson.{*, given}
import e.scala.*
encode[EOr[String]](E.name("test").toEOr[String])
encode[EOr[Int]](123.toEOr)
val encoder = makeEncoder[EOr[String]]
encoder.encode(E.name("test").toEOr[String])
encoder.encode("123".toEOr)
Since e's Codec is a combination of decoding and encoding, you can use makeCodec
instead of separately using makeDecoder
and makeEncoder
if you have both capabilities for a type.
import e.playjson.{*, given}
import e.scala.*
import play.api.libs.json.*
case class User(name: String, age: Int)
object User:
given userFormat: Format[User] = Json.format[User]
val codec = makeCodec[User]
codec.decode(Json.obj("foo" -> "bar"))
codec.decode(Json.obj("name" -> "Akif", "age" -> 29))
codec.encode(User("Akif", 29))