Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing support of explicitNulls option for JSON encoders of Schema.GenericRecord values #779

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ object JsonCodec {
out.write("{}")
} else {
val encoders = nonTransientFields.map(field => schemaEncoder(field.schema.asInstanceOf[Schema[Any]], cfg))
(value: ListMap[String, _], indent: Option[Int], out: Write) => {
(a: ListMap[String, _], indent: Option[Int], out: Write) => {
out.write('{')
val doPrettyPrint = indent ne None
var indent_ = indent
Expand All @@ -590,21 +590,22 @@ object JsonCodec {
}
var idx = 0
while (idx < nonTransientFields.length) {
val field = nonTransientFields(idx)
val fieldName = field.fieldName
val fieldValue = value(fieldName)
if (!isEmptyOptionalValue(field, fieldValue, cfg)) {
val field = nonTransientFields(idx)
val encoder = encoders(idx)
idx += 1
val name = field.fieldName
val value = a(name)
if (!isEmptyOptionalValue(field, value, cfg) && (!encoder.isNothing(value) || cfg.explicitNulls)) {
if (first) first = false
else {
out.write(',')
if (doPrettyPrint) pad(indent_, out)
}
strEnc.unsafeEncode(fieldName, indent_, out)
strEnc.unsafeEncode(name, indent_, out)
if (doPrettyPrint) out.write(" : ")
else out.write(':')
encoders(idx).unsafeEncode(fieldValue, indent_, out)
encoder.unsafeEncode(value, indent_, out)
}
idx += 1
}
if (doPrettyPrint) pad(indent, out)
out.write('}')
Expand Down Expand Up @@ -1099,7 +1100,7 @@ object JsonCodec {

private[codec] def caseClassEncoder[Z](schema: Schema.Record[Z], cfg: Config, discriminatorTuple: DiscriminatorTuple): ZJsonEncoder[Z] = {
val nonTransientFields = schema.nonTransientFields.map(_.asInstanceOf[Schema.Field[Z, Any]]).toArray
val fieldEncoders = nonTransientFields.map(s => JsonEncoder.schemaEncoder(s.schema, cfg, discriminatorTuple))
val encoders = nonTransientFields.map(s => JsonEncoder.schemaEncoder(s.schema, cfg, discriminatorTuple))
(a: Z, indent: Option[Int], out: Write) => {
out.write('{')
val doPrettyPrint = indent ne None
Expand All @@ -1120,20 +1121,20 @@ object JsonCodec {
}
var idx = 0
while (idx < nonTransientFields.length) {
val schema = nonTransientFields(idx)
val enc = fieldEncoders(idx)
val field = nonTransientFields(idx)
val encoder = encoders(idx)
idx += 1
val value = schema.get(a)
if (!isEmptyOptionalValue(schema, value, cfg) && (!enc.isNothing(value) || cfg.explicitNulls)) {
val value = field.get(a)
if (!isEmptyOptionalValue(field, value, cfg) && (!encoder.isNothing(value) || cfg.explicitNulls)) {
if (first) first = false
else {
out.write(',')
if (doPrettyPrint) pad(indent_, out)
}
strEnc.unsafeEncode(schema.fieldName, indent_, out)
strEnc.unsafeEncode(field.fieldName, indent_, out)
if (doPrettyPrint) out.write(" : ")
else out.write(':')
enc.unsafeEncode(value, indent_, out)
encoder.unsafeEncode(value, indent_, out)
}
}
if (doPrettyPrint) pad(indent, out)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,19 @@ object JsonCodecSpec extends ZIOSpecDefault {
"{}"
)
},
test("record with option fields encoded as null") {
test("record with option fields") {
assertEncodes(
recordWithOptionSchema,
ListMap[String, Any]("foo" -> Some("s"), "bar" -> None),
charSequenceToByteChunk("""{"foo":"s","bar":null}""")
charSequenceToByteChunk("""{"foo":"s"}""")
)
},
test("record with option fields and flag to encode nulls") {
assertEncodes(
recordWithOptionSchema,
ListMap[String, Any]("foo" -> Some("s"), "bar" -> None),
charSequenceToByteChunk("""{"foo":"s","bar":null}"""),
JsonCodec.Config.default.copy(explicitNulls = true)
)
},
test("case class with option fields omitted when empty") {
Expand Down Expand Up @@ -500,7 +508,7 @@ object JsonCodecSpec extends ZIOSpecDefault {
RecordExample.schema,
RecordExample(f1 = "test", f3 = Some("transient"), f20 = None, f21 = Vector.empty, f22 = Nil),
charSequenceToByteChunk(
"""{"$f1":"test","f20":null,"f21":[],"f22":[]}""".stripMargin
"""{"$f1":"test","f21":[],"f22":[]}""".stripMargin
)
)
}
Expand Down
Loading