zio-json icon indicating copy to clipboard operation
zio-json copied to clipboard

what is the intended semantics for encoding case objects?

Open cartazio opened this issue 3 years ago • 3 comments

i'm having a hard time finding info in the tests etc :)

cartazio avatar Mar 03 '21 01:03 cartazio

context: i've got some examples where the withNameOption style of enum encoding is what i want, and it looks like the current zio-json default is essentially the tag:{} rep. which seems like an odd choice efficiency wise :)

cartazio avatar Mar 03 '21 15:03 cartazio

The @jsonDiscriminator example from the Readme also applies to case objects, is this what you’re looking for?

test("cartazio0") {
  @jsonDiscriminator("type")
  sealed trait Fruit

  object Fruit {
    case object Avocado extends Fruit
    case object Banana  extends Fruit
    case object Tomato  extends Fruit

    implicit val encoder: JsonEncoder[Fruit] = DeriveJsonEncoder.gen[Fruit]
    implicit val decoder: JsonDecoder[Fruit] = DeriveJsonDecoder.gen[Fruit]
  }

  assert((Fruit.Avocado: Fruit).toJson)(equalTo("""{"type":"Avocado"}""")) &&
  assert("""{"type": "Avocado"}""".fromJson[Fruit])(equalTo(Right(Fruit.Avocado)))
}

fsvehla avatar Mar 03 '21 22:03 fsvehla

so in my case, the behavior i'm wanting/doing is the one you'd get from something like

implicit val decoder: JsonDecoder[Gender] = implicitly[JsonDecoder[String]].mapOrFail(x => Gender.withNameEither(x).leftMap(y => y.getMessage))
implicit val encoder: JsonEncoder[Gender] = implicitly[JsonEncoder[String]].contramap(_.toString())

this is partly cause of keeping compatibility with an existing API. And i guess i'm just slightly surprised that ZIO doesnt choose the more succinct choice in this case

this example is using the withNameEither operation via enumeratum package

cartazio avatar Mar 04 '21 15:03 cartazio