Skip to content

Commit

Permalink
Update docs + add new param to document encoder visitor
Browse files Browse the repository at this point in the history
  • Loading branch information
msosnicki committed Dec 4, 2023
1 parent 0df9929 commit 1accdd7
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 6 deletions.
14 changes: 13 additions & 1 deletion modules/core/src/smithy4s/Document.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,21 @@ object Document {
def fromSchema[A](
schema: Schema[A],
cache: Cache
): Encoder[A] =
fromSchema(schema, cache, explicitDefaultsEncoding = false)

def fromSchema[A](
schema: Schema[A],
cache: Cache,
explicitDefaultsEncoding: Boolean
): Encoder[A] = {
val makeEncoder =
schema.compile(new DocumentEncoderSchemaVisitor(cache))
schema.compile(
new DocumentEncoderSchemaVisitor(
cache,
explicitDefaultsEncoding = explicitDefaultsEncoding
)
)
new Encoder[A] {
def encode(a: A): Document = {
makeEncoder.apply(a)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,14 @@ object DocumentEncoder {
}

class DocumentEncoderSchemaVisitor(
val cache: CompilationCache[DocumentEncoder]
val cache: CompilationCache[DocumentEncoder],
val explicitDefaultsEncoding: Boolean
) extends SchemaVisitor.Cached[DocumentEncoder] {
self =>

def this(cache: CompilationCache[DocumentEncoder]) =
this(cache, explicitDefaultsEncoding = false)

override def primitive[P](
shapeId: ShapeId,
hints: Hints,
Expand Down Expand Up @@ -197,9 +202,12 @@ class DocumentEncoderSchemaVisitor(
.map(_.value)
.getOrElse(field.label)
(s, builder) =>
field.getUnlessDefault(s).foreach { value =>
builder.+=(jsonLabel -> encoder.apply(value))
}
if (explicitDefaultsEncoding) {
builder.+=(jsonLabel -> encoder.apply(field.get(s)))
} else
field.getUnlessDefault(s).foreach { value =>
builder.+=(jsonLabel -> encoder.apply(value))
}
}

val encoders = fields.map(field => fieldEncoder(field))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ See the section about [unions](../../04-codegen/02-unions.md) for a detailed des

## Explicit Null Encoding

By default, optional structure fields that are set to `None` will be excluded from encoded structures. If you wish to change this so that instead they are included and set to `null` explicitly, you can do so by calling `.withExplicitDefaultsEncoding(true)`.
By default, optional properties (headers, query parameters, structure fields) that are set to `None` and optional properties that are set to default value will be excluded during encoding process. If you wish to change this so that instead they are included and set to `null` explicitly, you can do so by calling `.withExplicitDefaultsEncoding(true)`.

## Supported traits

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import smithy4s.Document
import org.http4s.client.Client
import smithy4s.example.OperationInput
import cats.effect.kernel.Deferred
import smithy4s.schema.CompilationCache

object NullsAndDefaultEncodingSuite extends SimpleIOSuite with CirceInstances {

Expand Down Expand Up @@ -115,6 +116,33 @@ object NullsAndDefaultEncodingSuite extends SimpleIOSuite with CirceInstances {
)
}

test("document encoder - all default - explicit defaults encoding = true") {
val result = Document.Encoder
.fromSchema(
OperationOutput.schema,
CompilationCache.nop,
explicitDefaultsEncoding = true
)
.encode(OperationOutput())
IO.pure(
assert.same(
Document.obj(
"optional" -> Document.nullDoc,
"optionalHeader" -> Document.nullDoc,
"optionalWithDefault" -> Document.fromString("optional-default"),
"requiredWithDefault" -> Document.fromString("required-default"),
"optionalHeaderWithDefault" -> Document.fromString(
"optional-header-with-default"
),
"requiredHeaderWithDefault" -> Document.fromString(
"required-header-with-default"
)
),
result
)
)
}

test("document encoder - default overrides") {
val result = Document.Encoder
.fromSchema(OperationOutput.schema)
Expand Down

0 comments on commit 1accdd7

Please sign in to comment.