Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
pablf committed Jun 30, 2024
1 parent 3cb2726 commit 09ca54e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,10 @@ private case class DeriveSchema()(using val ctx: Quotes) {
val cases = typesAndLabels.map { case (tpe, label) => deriveCase[T](tpe, label, newStack) }

val numParentFields: Int = TypeRepr.of[T].typeSymbol.declaredFields.length
val childrenFields = TypeRepr.of[T].typeSymbol.children.map(_.declaredFields.length)
val childrenFieldsConstructor = TypeRepr.of[T].typeSymbol.children.map(_.caseFields.length)
val isSimpleEnum: Boolean = childrenFieldsConstructor.forall( _ == 0) && childrenFields.forall( _ <= numParentFields)
val childrens = TypeRepr.of[T].typeSymbol.children
val childrenFields = children.map(_.declaredFields.length)
val childrenFieldsConstructor = children.map(_.caseFields.length)
val isSimpleEnum: Boolean = childrenFieldsConstructor.forall( _ == 0) && childrenFields.forall( _ <= numParentFields) && children.flatMap(_.children).isEmpty
val hasSimpleEnumAnn: Boolean = TypeRepr.of[T].typeSymbol.hasAnnotation(TypeRepr.of[_root_.zio.schema.annotation.simpleEnum].typeSymbol)

val docAnnotationExpr = TypeRepr.of[T].typeSymbol.docstring.map { docstring =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ object DeriveSchemaSpec extends ZIOSpecDefault with VersionSpecificDeriveSchemaS
sealed trait SimpleEnum2
case class SimpleClass2() extends SimpleEnum2

sealed trait NonSimpleTrait
sealed trait NonSimpleMiddle extends NonSimpleTrait
case class NonSimpleLeaf() extends NonSimpleMiddle

sealed abstract class AbstractBaseClass(val x: Int)
final case class ConcreteClass1(override val x: Int, y: Int) extends AbstractBaseClass(x)
final case class ConcreteClass2(override val x: Int, s: String) extends AbstractBaseClass(x)
Expand Down Expand Up @@ -493,6 +497,10 @@ object DeriveSchemaSpec extends ZIOSpecDefault with VersionSpecificDeriveSchemaS
val derived = DeriveSchema.gen[SimpleEnum2]
assertTrue(derived.annotations == Chunk(simpleEnum(true)))
},
test("doesn't derives simpleEnum when extending subclasses") {
val derived = DeriveSchema.gen[NonSimpleTrait]
assertTrue(derived.annotations.isEmpty)
},
test("correctly derives schema for abstract sealed class with case class subclasses") {
val derived = DeriveSchema.gen[AbstractBaseClass]
val expected: Schema[AbstractBaseClass] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ object JsonCodec {
private def enumEncoder[Z](schema: Schema.Enum[Z], cfg: Config, cases: Schema.Case[Z, _]*): ZJsonEncoder[Z] =
// if all cases are CaseClass0, encode as a String
if (schema.annotations.exists(_.isInstanceOf[simpleEnum])) {
if (!cases.forall(_.schema.isInstanceOf[Schema.CaseClass0[_]])) throw new Throwable("@simpleEnum annotation should not be added to non-simple enumerations")
val caseMap: Map[Z, String] =
schema.nonTransientCases
.map(
Expand Down Expand Up @@ -699,7 +700,8 @@ object JsonCodec {
}.toMap

// if all cases are CaseClass0, decode as String
if (cases.forall(_.schema.isInstanceOf[Schema.CaseClass0[_]])) {
if (schema.annotations.exists(_.isInstanceOf[simpleEnum])) {
if (!cases.forall(_.schema.isInstanceOf[Schema.CaseClass0[_]])) throw new Throwable("@simpleEnum annotation should not be added to non-simple enumerations")
val caseMap: Map[String, Z] =
cases.map(case_ => case_.id -> case_.schema.asInstanceOf[Schema.CaseClass0[Z]].defaultConstruct()).toMap
ZJsonDecoder.string.mapOrFail(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,13 @@ object JsonCodecSpec extends ZIOSpecDefault {
charSequenceToByteChunk("""{"oneOf":{"_type":"StringValue2","value":"foo2"}}""")
)
},
test("ADT with intermediate enumeration") {
assertEncodes(
Schema[IntermediateEnum],
IntermediateEnum.FinalElem,
charSequenceToByteChunk(""""FinalElem"""")
)
},
test("case class") {
assertEncodes(
searchRequestWithTransientFieldSchema,
Expand Down Expand Up @@ -1226,6 +1233,12 @@ object JsonCodecSpec extends ZIOSpecDefault {
Enumeration2(BooleanValue2(false))
)
},
test("ADT with intermediate enumeration") {
assertEncodesThenDecodes(
Schema[IntermediateEnum],
IntermediateEnum.FinalElem
)
},
test("ADT with noDiscriminator") {
assertEncodesThenDecodes(
Schema[Enumeration3],
Expand Down Expand Up @@ -1742,6 +1755,16 @@ object JsonCodecSpec extends ZIOSpecDefault {
implicit val schema: Schema[Enumeration3] = DeriveSchema.gen[Enumeration3]
}

sealed trait IntermediateEnum

object IntermediateEnum {
sealed trait IntermediateElem extends IntermediateEnum
case object FinalElem extends IntermediateEnum
implicit val schema: zio.schema.Schema[IntermediateEnum] = zio.schema.DeriveSchema.gen[IntermediateEnum]
}



sealed trait Color

object Color {
Expand Down

0 comments on commit 09ca54e

Please sign in to comment.