Skip to content

Inconsistent schema derivation for nested enums between Scala 2 and Scala 3 #1030

@jirihausner

Description

@jirihausner

Reproducer:

//> using dep dev.zio::zio-schema:1.8.3
//> using dep dev.zio::zio-schema-derivation:1.8.3

sealed trait NestedEnum

object NestedEnum {

  sealed trait Enum extends NestedEnum
  case object Case  extends Enum

  implicit val schema: zio.schema.Schema[NestedEnum] = zio.schema.DeriveSchema.gen
}

sealed trait DeeplyNestedEnum

object DeeplyNestedEnum {

  sealed trait DeepEnumA extends DeeplyNestedEnum
  sealed trait DeepEnumB extends DeeplyNestedEnum
  sealed trait EnumA extends DeepEnumA
  sealed trait EnumB extends DeepEnumB
  case object CaseA  extends EnumA
  case object CaseB  extends EnumB

  implicit val schema: zio.schema.Schema[DeeplyNestedEnum] = zio.schema.DeriveSchema.gen
}

sealed trait HierarchicalEnum

object HierarchicalEnum {

  sealed trait EnumA                  extends HierarchicalEnum
  sealed trait EnumB                  extends HierarchicalEnum
  sealed trait DeepEnumA              extends EnumA
  sealed trait DeepEnumB              extends EnumB
  case class CaseA(value: String)     extends EnumA
  case object CaseB                   extends EnumB
  case class DeepCaseA(value: String) extends DeepEnumA
  case object DeepCaseB               extends DeepEnumB

  implicit val schema: zio.schema.Schema[HierarchicalEnum] = zio.schema.DeriveSchema.gen
}

object Main {

  def main(args: Array[String]) = {
    println(s"schema: ${NestedEnum.schema.ast.toString}")
    println(s"annotations: ${NestedEnum.schema.annotations.toString}\n")
    println(s"schema: ${DeeplyNestedEnum.schema.ast.toString}")
    println(s"annotations: ${DeeplyNestedEnum.schema.annotations.toString}\n")
    println(s"schema: ${HierarchicalEnum.schema.ast.toString}")
    println(s"annotations: ${HierarchicalEnum.schema.annotations.toString}")
  }
}
$ scala-cli run . --main-class Main -S 2
schema: enum
|--Case: record

annotations: Chunk(simpleEnum(true))

schema: enum
|--CaseA: record
|--CaseB: record

annotations: Chunk(simpleEnum(true))

schema: enum
|--DeepCaseA: record
|----value: string
|--CaseA: record
|----value: string
|--DeepCaseB: record
|--CaseB: record

annotations: Chunk()

vs.

$ scala-cli run . --main-class Main -S 3
schema: enum
|--Enum: enum
|----Case: record

annotations: Chunk()

schema: enum
|--DeepEnumA: enum
|----EnumA: enum
|------CaseA: record
|--DeepEnumB: enum
|----EnumB: enum
|------CaseB: record

annotations: Chunk()

schema: enum
|--EnumA: enum
|----DeepEnumA: enum
|------DeepCaseA: record
|--------value: string
|----CaseA: record
|------value: string
|--EnumB: enum
|----DeepEnumB: enum
|------DeepCaseB: record
|----CaseB: record

annotations: Chunk()

Expected behavior: derived schema should be consistent across Scala 2 and Scala 3 (including simpleEnum annotations).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions