diff --git a/modules/bootstrapped/test/src/smithy4s/http/MetadataDecoderSpec.scala b/modules/bootstrapped/test/src/smithy4s/http/MetadataDecoderSpec.scala new file mode 100644 index 000000000..a859e9997 --- /dev/null +++ b/modules/bootstrapped/test/src/smithy4s/http/MetadataDecoderSpec.scala @@ -0,0 +1,44 @@ +package smithy4s.http + +import munit._ +import smithy4s.schema.Schema +import smithy.api +// import smithy4s.schema.Field + +final class MetadataDecoderSpec extends FunSuite { + test("Optional header") { + case class Foo(deviceType: Option[String]) + val schema = + Schema + .struct( + Schema.string + .optional[Foo]("deviceType", _.deviceType) + .addHints(api.HttpHeader("x-device-type")) + .addHints(api.Input()) + )(Foo(_)) + .addHints(smithy4s.internals.InputOutput.Input.widen) + + val decoder = Metadata.Decoder.fromSchema(schema) + val result = decoder.decode(Metadata()) + + assertEquals(result, Right(Foo(None))) + } + + test("Optional bijection header") { + case class Foo(name: Option[String]) + val schema: Schema[Foo] = { + val field = Schema.string.option + .biject[Option[String]](identity[Option[String]](_))(identity(_)) + .required[Foo]("name", _.name) + .addHints(smithy.api.HttpHeader("X-Name")) + Schema + .struct(field)(Foo(_)) + .addHints(smithy4s.internals.InputOutput.Input.widen) + } + + val decoder = Metadata.Decoder.fromSchema(schema) + val result = decoder.decode(Metadata()) + + assertEquals(result, Right(Foo(None))) + } +} diff --git a/modules/core/src/smithy4s/schema/Schema.scala b/modules/core/src/smithy4s/schema/Schema.scala index d352f23a9..feab539ab 100644 --- a/modules/core/src/smithy4s/schema/Schema.scala +++ b/modules/core/src/smithy4s/schema/Schema.scala @@ -291,6 +291,8 @@ object Schema { private object OptionDefaultVisitor extends SchemaVisitor.Default[Option] { def default[A] : Option[A] = None override def option[A](schema: Schema[A]) : Option[Option[A]] = Some(None) + override def biject[A, B](schema: Schema[A], bijection: Bijection[A, B]): Option[B] = + this.apply(schema).map(bijection.to) } def operation(id: ShapeId): OperationSchema[Unit, Nothing, Unit, Nothing, Nothing] =