Skip to content

Commit

Permalink
Fix JSON decoding of empty objects
Browse files Browse the repository at this point in the history
- discriminated case object
- case object with @rejectExtraField
  • Loading branch information
guersam committed Jul 4, 2024
1 parent 91899ff commit d9a785c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,29 @@ object JsonCodec {
import JsonCodec.JsonDecoder.schemaDecoder

private[codec] def caseClass0Decoder[Z](discriminator: Int, schema: Schema.CaseClass0[Z]): ZJsonDecoder[Z] = { (trace: List[JsonError], in: RetractReader) =>
if (discriminator == -1) Codecs.unitDecoder.unsafeDecode(trace, in)
def skipField(): Unit = {
val rejectExtraFields = schema.annotations.collectFirst({ case _: rejectExtraFields => () }).isDefined
if (rejectExtraFields) {
throw UnsafeJson(JsonError.Message("extra field") :: trace)
}
Lexer.char(trace, in, '"')
Lexer.skipString(trace, in)
Lexer.char(trace, in, ':')
Lexer.skipValue(trace, in)
}

if (discriminator == -2) {
while (Lexer.nextField(trace, in)) { skipField() }
} else {
if (discriminator == -1) {
Lexer.char(trace, in, '{')
}
if (Lexer.firstField(trace, in)) {
skipField()
while (Lexer.nextField(trace, in)) { skipField() }
}
}

schema.defaultConstruct()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,12 @@ object JsonCodecSpec extends ZIOSpecDefault {
PersonWithRejectExtraFields.schema,
"""{"name":"test","age":10,"extraField":10}""",
JsonError.Message("extra field") :: Nil
)
) &>
assertDecodesToError(
CaseClass0WithRejectExtraFields.schema,
"""{"extraField":10}""",
JsonError.Message("extra field") :: Nil
)
},
test("transient field annotation") {
assertDecodes(
Expand Down Expand Up @@ -1242,6 +1247,13 @@ object JsonCodecSpec extends ZIOSpecDefault {
assertEncodesThenDecodes(Schema[Command], Command.Cash) &>
assertEncodesThenDecodes(Schema[Command], Command.Buy(100))
},
test("decode discriminated case objects in array")(
assertDecodes(Schema[List[Command]], Command.Cash :: Nil, charSequenceToByteChunk("""[{"type":"Cash"}]"""))
),
test("decode discriminated case objects with extra fields")(
assertDecodes(Schema[Command], Command.Cash, charSequenceToByteChunk("""{"type":"Cash","extraField":1}""")) &>
assertDecodes(Schema[Command], Command.Cash, charSequenceToByteChunk("""{"extraField":1,"type":"Cash"}""""))
),
suite("of case objects")(
test("without annotation")(
assertEncodesThenDecodes(Schema[Color], Color.Red)
Expand Down Expand Up @@ -1593,6 +1605,12 @@ object JsonCodecSpec extends ZIOSpecDefault {

val schema: Schema[PersonWithRejectExtraFields] = DeriveSchema.gen[PersonWithRejectExtraFields]
}

@rejectExtraFields final case class CaseClass0WithRejectExtraFields()
object CaseClass0WithRejectExtraFields {
val schema: Schema[CaseClass0WithRejectExtraFields] = DeriveSchema.gen[CaseClass0WithRejectExtraFields]
}

case class FieldDefaultValueSearchRequest(
query: String,
pageNumber: Int,
Expand Down

0 comments on commit d9a785c

Please sign in to comment.