Skip to content

Commit

Permalink
More efficient encoding of case classes
Browse files Browse the repository at this point in the history
  • Loading branch information
plokhotnyuk committed Jan 29, 2025
1 parent bb1e1d1 commit 89edef5
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
14 changes: 10 additions & 4 deletions zio-json/shared/src/main/scala-2.x/zio/json/macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,15 @@ object DeriveJsonEncoder {
var idx = 0
var prevFields = false // whether any fields have been written
while (idx < fields.length) {
val field = fields(idx)
val p = field.p.dereference(a)
field.encodeOrSkip(p) { () =>
val field = fields(idx)
val p = field.p.dereference(a)
val encoder = field.encoder
if (
(field.withExplicitNulls && field.withExplicitEmptyCollections) ||
(field.withExplicitNulls && !encoder.isEmpty(p)) ||
(field.withExplicitEmptyCollections && !encoder.isNothing(p)) ||
(!encoder.isEmpty(p) && !encoder.isNothing(p))
) {
// if we have at least one field already, we need a comma
if (prevFields) {
out.write(',')
Expand All @@ -557,7 +563,7 @@ object DeriveJsonEncoder {
JsonEncoder.string.unsafeEncode(field.name, indent_, out)
if (indent.isEmpty) out.write(':')
else out.write(" : ")
field.encoder.unsafeEncode(p, indent_, out)
encoder.unsafeEncode(p, indent_, out)
prevFields = true // record that we have at least one field so far
}
idx += 1
Expand Down
6 changes: 5 additions & 1 deletion zio-json/shared/src/main/scala-3/zio/json/macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,11 @@ sealed class JsonEncoderDerivation(config: JsonCodecConfiguration) extends Deriv
while (idx < fields.length) {
val field = fields(idx)
val p = field.p.deref(a)
field.encodeOrSkip(p) { () =>
val encoder = field.encoder
if ((field.withExplicitNulls && field.withExplicitEmptyCollections) ||
(field.withExplicitNulls && !encoder.isEmpty(p)) ||
(field.withExplicitEmptyCollections && !encoder.isNothing(p)) ||
(!encoder.isEmpty(p) && !encoder.isNothing(p))) {
// if we have at least one field already, we need a comma
if (prevFields) {
out.write(',')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ private[json] class FieldEncoder[T, P](
val p: P,
val name: String,
val encoder: JsonEncoder[T],
withExplicitNulls: Boolean,
withExplicitEmptyCollections: Boolean
val withExplicitNulls: Boolean,
val withExplicitEmptyCollections: Boolean
) {
private[this] val _encodeOrSkip: T => (() => Unit) => Unit =
if (withExplicitNulls && withExplicitEmptyCollections) { _ => encode =>
Expand Down

0 comments on commit 89edef5

Please sign in to comment.