Skip to content

Commit

Permalink
Fix JSON decoding of empty objects (#710)
Browse files Browse the repository at this point in the history
* Fix JSON decoding of empty objects

- discriminated case object
- case object with @rejectExtraField

* fmt test sources

* Simplify test
  • Loading branch information
guersam authored Jul 9, 2024
1 parent 91899ff commit 975539a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 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(
schemaObject.annotate(rejectExtraFields()),
"""{"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,7 @@ object JsonCodecSpec extends ZIOSpecDefault {

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

case class FieldDefaultValueSearchRequest(
query: String,
pageNumber: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ object DefaultValueSpec extends ZIOSpecDefault {

def spec: Spec[TestEnvironment, Any] =
suite("Custom Spec")(
customSuite,
customSuite
) @@ timeout(90.seconds)

private val customSuite = suite("custom")(
Expand All @@ -24,7 +24,7 @@ object DefaultValueSpec extends ZIOSpecDefault {
)
)

case class WithDefaultValue(orderId:Int, description: String = "desc")
case class WithDefaultValue(orderId: Int, description: String = "desc")

object WithDefaultValue {
implicit lazy val schema: Schema[WithDefaultValue] = DeriveSchema.gen[WithDefaultValue]
Expand Down

0 comments on commit 975539a

Please sign in to comment.