Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Inconsistent encoding/decoding of nested sum types #2110

@matil019

Description

@matil019

As of 0.14.5, derived encoder and decoder of a nested sum type are inconsistent. The Decoder can't decode a JSON encoded by the Encoder.

Minimal example:

import io.circe.Decoder
import io.circe.Encoder
import io.circe.generic.semiauto.deriveDecoder
import io.circe.generic.semiauto.deriveEncoder
import io.circe.parser.decode
import io.circe.syntax._

sealed trait Top

object Top {
  sealed trait Middle extends Top

  object Middle {
    case object Bottom extends Middle
  }

  implicit val decodeTop: Decoder[Top] = deriveDecoder
  implicit val encodeTop: Encoder[Top] = deriveEncoder
}

object Main {
  def main(args: Array[String]): Unit = {
    val s = (Top.Middle.Bottom: Top).asJson.noSpaces
    println(s)
    println(decode[Top](s))
  }
}

Expected output (scala:3.2.2, circe:0.14.3)

{"Middle":{"Bottom":{}}}
Right(Bottom)

Actual output (scala:3.2.2, circe:0.14.5)

{"Middle":{"Bottom":{}}}
Left(DecodingFailure at .Middle: type Top has no class/object/case named 'Middle'.)

^ In this case, the decoder can decode {"Bottom":{}} to Bottom.


It turned out that both of the above are also inconsistent with scala 2.13 build of circe:

Output (scala:2.13.0, circe:0.14.3/0.14.5)

{"Bottom":{}}
Right(Bottom)

So I'm not sure which encoding is correct.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions