Skip to content

Commit

Permalink
Support 1.0 open enums
Browse files Browse the repository at this point in the history
  • Loading branch information
kubukoz committed Oct 5, 2023
1 parent 7a558e8 commit 1895e2c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,19 @@ private[dynamic] object Compiler {
)
}

if (shape.traits.contains(IdRef("alloy#openEnum"))) {
update(id, shape.traits, makeStringEnum(id, values, shape.traits))
}

private def makeStringEnum(
id: ShapeId,
values: List[EnumValue[Int]],
traits: Map[IdRef, Document]
) = {
if (traits.contains(IdRef("alloy#openEnum"))) {
// the runtime representation of normal enums is Int, but for open enums it's String to support arbitrary unknown values.
val mappedValues = values.map(_.map(_.asLeft[String]))

val theEnum = enumeration[Either[Int, String]](
enumeration[Either[Int, String]](
_.fold(
mappedValues,
unknownValueString =>
Expand All @@ -262,13 +270,8 @@ private[dynamic] object Compiler {
EnumTag.OpenStringEnum(_.asRight[Int]),
mappedValues
)

update(id, shape.traits, theEnum)
} else {
val theEnum = stringEnumeration(values, values)

update(id, shape.traits, theEnum)
}
} else
stringEnumeration(values, values)

}

Expand Down Expand Up @@ -356,7 +359,7 @@ private[dynamic] object Compiler {
update(
id,
shape.traits,
stringEnumeration(values, values)
makeStringEnum(id, values, shape.traits)
)
}
case _ => update(id, shape.traits, string)
Expand Down
17 changes: 17 additions & 0 deletions modules/dynamic/test/src-jvm/smithy4s/dynamic/EnumSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ class EnumSpec extends DummyIO.Suite {
ICE = 42,
FIRE = 10
}
@enum([
{ value: "Vanilla" },
{ value: "Ice" }
])
@alloy#openEnum
string Open10Enum
"""

val compiled = Utils.compile(model)
Expand Down Expand Up @@ -262,6 +269,16 @@ class EnumSpec extends DummyIO.Suite {
}
}

test("Smithy 1.0 open string enums can be decoded to UNKNOWN") {
compiled.map { index =>
val schema = index
.getSchema(ShapeId("example", "Open10Enum"))
.getOrElse(fail("Error: shape missing"))

decodeEncodeCheck(schema)(Document.fromString("not a known value"))
}
}

private def decodeEncodeCheck[A](schema: Schema[A])(input: Document) = {
val decoded = Document.Decoder
.fromSchema(schema)
Expand Down

0 comments on commit 1895e2c

Please sign in to comment.