smithy4s icon indicating copy to clipboard operation
smithy4s copied to clipboard

Empty default handling

Open kubukoz opened this issue 2 years ago • 3 comments

Inference of defaults on members with null @default

In #782, we added this semantic: adding an empty @default trait to a shape makes that shape's default the "empty" value of the target type.

For example:


//> using scala "2.13.10"
//> using option "-feature"
//> using lib "software.amazon.smithy:smithy-model:1.28.1"
//> using lib "com.disneystreaming.smithy4s::smithy4s-dynamic:0.17.5"
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.traits.DefaultTrait
import smithy4s.dynamic.DynamicSchemaIndex
import smithy4s.schema.Schema
import scala.language.existentials

val s =
  """$version: "2"
    |namespace test
    |
    |structure Hello {
    |  @default s: String
    |}
    |""".stripMargin

val m = Model.assembler().addUnparsedModel("test.smithy", s).assemble().unwrap()

DynamicSchemaIndex
  .loadModel(m)
  .toTry
  .get
  .getSchema(smithy4s.ShapeId("test", "Hello"))
  .get
  .asInstanceOf[Schema.StructSchema[_]]
  .fields
  .head
  .instance
  .getDefaultValue
// res0: Option[_1.T] = Some(value = "")

Quoting Michael's comment here:

Setting a member to have a default value of null is only useful if the shape targeted by the member defines a default value. It's only meaning is that it cancels out the default value of the target shape.

With that in mind, I believe this part is wrong:

// res0: Option[_1.T] = Some(value = "")

I believe it should be None instead.

Defaults on document shapes

However! I think the behavior is correct for documents:

Setting a document type null is also meaningless and there's no way to set a document type to have a default value of null since that's already the assumed value if it isn't specified

so if the schema in question was @default s: Document, that field's default should be Some(Document.DNull).


Related: https://github.com/disneystreaming/smithy4s/pull/823 introduced defaults for the schema of the Dynamic model, which I believe won't work if we update the semantics for non-documents (@default will be different from @default([])).

kubukoz avatar Mar 20 '23 13:03 kubukoz

sigh I'm really not liking the distinction between :

  • @default s: Document <=> s: Option[Document] = Some(Document.DNull)
  • @default s: Integer <=> s: Option[Int] = None

I'm gonna have to digest this further (it's not because AWS says something that it's the right thing to do)

Baccata avatar Mar 23 '23 16:03 Baccata

if you ask me, @default s: Document may as well decode to None. I'm just not a fan of the current semantics

kubukoz avatar Mar 31 '23 14:03 kubukoz

I'm just not a fan of the current semantics

Agreed

Baccata avatar Mar 31 '23 15:03 Baccata