diff --git a/modules/core/src/main/scala/playground/CompilationError.scala b/modules/core/src/main/scala/playground/CompilationError.scala index f83391a9..ce14976f 100644 --- a/modules/core/src/main/scala/playground/CompilationError.scala +++ b/modules/core/src/main/scala/playground/CompilationError.scala @@ -138,6 +138,9 @@ sealed trait CompilationErrorDetails extends Product with Serializable { case EmptyStruct(possibleValues) => s"found empty struct, expected one of: ${possibleValues.mkString_(", ")}." + case InvalidIntEnumValue(value) => + s"Invalid value for open int enum: $value - must be an integer." + case UnknownEnumValue(name, possibleValues) => s"Unknown enum value: $name. Available values: ${possibleValues.mkString(", ")}" @@ -228,6 +231,10 @@ object CompilationErrorDetails { possibleValues: NonEmptyList[String] ) extends CompilationErrorDetails + final case class InvalidIntEnumValue( + value: String + ) extends CompilationErrorDetails + final case class UnknownEnumValue( value: String, possibleValues: List[String], diff --git a/modules/core/src/main/scala/playground/NodeEncoderVisitor.scala b/modules/core/src/main/scala/playground/NodeEncoderVisitor.scala index 691ddaf1..ede62fd3 100644 --- a/modules/core/src/main/scala/playground/NodeEncoderVisitor.scala +++ b/modules/core/src/main/scala/playground/NodeEncoderVisitor.scala @@ -28,6 +28,7 @@ import smithy4s.capability.EncoderK import smithy4s.schema.Alt import smithy4s.schema.CollectionTag import smithy4s.schema.EnumTag +import smithy4s.schema.EnumTag._ import smithy4s.schema.EnumValue import smithy4s.schema.Field import smithy4s.schema.Primitive @@ -164,7 +165,12 @@ object NodeEncoderVisitor extends SchemaVisitor[NodeEncoder] { self => tag: EnumTag[E], values: List[EnumValue[E]], total: E => EnumValue[E], - ): NodeEncoder[E] = string.contramap(total(_).name) + ): NodeEncoder[E] = + tag match { + case ClosedIntEnum | ClosedStringEnum => string.contramap(total(_).name) + // todo: test + case OpenIntEnum(_) | OpenStringEnum(_) => string.contramap(total(_).stringValue) + } def struct[S]( shapeId: ShapeId, diff --git a/modules/core/src/main/scala/playground/QueryCompilerVisitor.scala b/modules/core/src/main/scala/playground/QueryCompilerVisitor.scala index b31b9534..af8eae81 100644 --- a/modules/core/src/main/scala/playground/QueryCompilerVisitor.scala +++ b/modules/core/src/main/scala/playground/QueryCompilerVisitor.scala @@ -21,6 +21,8 @@ import smithy4s.Timestamp import smithy4s.schema.Alt import smithy4s.schema.CollectionTag import smithy4s.schema.EnumTag +import smithy4s.schema.EnumTag.OpenIntEnum +import smithy4s.schema.EnumTag.OpenStringEnum import smithy4s.schema.EnumValue import smithy4s.schema.Field import smithy4s.schema.Primitive @@ -483,7 +485,20 @@ object QueryCompilerVisitorInternal extends SchemaVisitor[QueryCompiler] { Ior.bothNec(CompilationError.warning(EnumFallback(v.name), range).deprecated, v.value) case (None, None) => - Ior.leftNec(CompilationError.error(UnknownEnumValue(name, values.map(_.name)), range)) + tag match { + // todo: test + case OpenIntEnum(unknown) => + name + .toIntOption + .toRightIor(CompilationError.error(InvalidIntEnumValue(name), range)) + .toIorNec + .map(unknown) + + // todo: test + case OpenStringEnum(unknown) => unknown(name).pure[QueryCompiler.Result] + case _ => + Ior.leftNec(CompilationError.error(UnknownEnumValue(name, values.map(_.name)), range)) + } } } diff --git a/modules/core/src/test/smithy/demo.smithy b/modules/core/src/test/smithy/demo.smithy index 80f04d05..5dc63131 100644 --- a/modules/core/src/test/smithy/demo.smithy +++ b/modules/core/src/test/smithy/demo.smithy @@ -3,6 +3,7 @@ $version: "2" namespace demo.smithy use alloy#UUID +use alloy#openEnum use alloy#simpleRestJson use smithy4s.meta#indexedSeq use smithy4s.meta#refinement @@ -67,9 +68,10 @@ structure CreateHeroInput { friendSet: FriendSet hasNewtypes: HasNewtypes hasDeprecations: HasDeprecations - doc: Document, - sparse: SampleSparseList, + doc: Document + sparse: SampleSparseList sparseMap: SampleSparseMap + tier: PrivacyTier } @uniqueItems @@ -290,7 +292,6 @@ structure HasMixin with [SampleMixin] { name: String } - @sparse list SampleSparseList { member: Integer @@ -301,3 +302,15 @@ map SampleSparseMap { key: String value: Integer } + +@openEnum +enum OpenStringEnum { + ICE + FIRE +} + +@openEnum +intEnum OpenIntEnum { + ICE = 1 + FIRE = 2 +} diff --git a/modules/language-support/src/main/scala/playground/language/CompletionVisitor.scala b/modules/language-support/src/main/scala/playground/language/CompletionVisitor.scala index f8421a93..783cc16e 100644 --- a/modules/language-support/src/main/scala/playground/language/CompletionVisitor.scala +++ b/modules/language-support/src/main/scala/playground/language/CompletionVisitor.scala @@ -33,7 +33,7 @@ import smithy4s.dynamic.DynamicSchemaIndex import smithy4s.schema.Alt import smithy4s.schema.CollectionTag import smithy4s.schema.EnumTag -import smithy4s.schema.EnumTag.IntEnum +import smithy4s.schema.EnumTag._ import smithy4s.schema.EnumValue import smithy4s.schema.Field import smithy4s.schema.Primitive @@ -251,8 +251,10 @@ object CompletionItem { case e @ EnumerationSchema(_, _, _, _, _) => e.tag match { - case IntEnum() => now(s"intEnum ${e.shapeId.name}") - case _ => now(s"enum ${e.shapeId.name}") + case ClosedIntEnum => now(s"intEnum ${e.shapeId.name}") + case OpenIntEnum(_) => now(s"@openEnum intEnum ${e.shapeId.name}") + case OpenStringEnum(_) => now(s"@openEnum enum ${e.shapeId.name}") + case ClosedStringEnum => now(s"enum ${e.shapeId.name}") } case MapSchema(shapeId, _, key, value) => diff --git a/project/plugins.sbt b/project/plugins.sbt index b4014537..816f4c66 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,3 @@ -ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always - addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.11") addSbtPlugin("org.typelevel" % "sbt-tpolecat" % "0.5.2")