Skip to content

Commit

Permalink
Yet more efficient encoding of sum types (#1345)
Browse files Browse the repository at this point in the history
  • Loading branch information
plokhotnyuk authored Feb 27, 2025
1 parent 1e27996 commit 5bd5dd3
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 16 deletions.
15 changes: 7 additions & 8 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 @@ -541,8 +541,7 @@ object DeriveJsonEncoder {
out.write(',')
JsonEncoder.pad(indent_, out)
} else prevFields = true
if (indent.isEmpty) out.write(field.encodedName)
else out.write(field.prettyEncodedName)
out.write(if (indent eq None) field.encodedName else field.prettyEncodedName)
field.encoder.unsafeEncode(p, indent_, out)
}
}
Expand Down Expand Up @@ -614,17 +613,17 @@ object DeriveJsonEncoder {
val indent_ = JsonEncoder.bump(indent)
JsonEncoder.pad(indent_, out)
out.write(encodedNames(idx))
if (indent.isEmpty) out.write(':')
if (indent eq None) out.write(':')
else out.write(" : ")
tcs(idx).unsafeEncode(casts(idx)(a), indent_, out)
tcs(idx).unsafeEncode(a, indent_, out)
JsonEncoder.pad(indent, out)
out.write('}')
}

override def toJsonAST(a: A): Either[String, Json] = {
var idx = 0
while (!casts(idx).isDefinedAt(a)) idx += 1
tcs(idx).toJsonAST(casts(idx)(a)).map(inner => new Json.Obj(Chunk(names(idx) -> inner)))
tcs(idx).toJsonAST(a).map(inner => new Json.Obj(Chunk(names(idx) -> inner)))
}
}
} else {
Expand All @@ -640,17 +639,17 @@ object DeriveJsonEncoder {
val indent_ = JsonEncoder.bump(indent)
JsonEncoder.pad(indent_, out)
out.write(encodedHintFieldName)
if (indent.isEmpty) out.write(':')
if (indent eq None) out.write(':')
else out.write(" : ")
out.write(encodedNames(idx))
// whitespace is always off by 2 spaces at the end, probably not worth fixing
tcs(idx).unsafeEncode(casts(idx)(a), indent, new NestedWriter(out, indent_))
tcs(idx).unsafeEncode(a, indent, new NestedWriter(out, indent_))
}

override final def toJsonAST(a: A): Either[String, Json] = {
var idx = 0
while (!casts(idx).isDefinedAt(a)) idx += 1
tcs(idx).toJsonAST(casts(idx)(a)).flatMap {
tcs(idx).toJsonAST(a).flatMap {
case o: Json.Obj =>
val hintField = hintFieldName -> new Json.Str(names(idx))
new Right(new Json.Obj(hintField +: o.fields)) // hint field is always first
Expand Down
15 changes: 7 additions & 8 deletions zio-json/shared/src/main/scala-3/zio/json/macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,7 @@ sealed class JsonEncoderDerivation(config: JsonCodecConfiguration) extends Deriv
out.write(',')
JsonEncoder.pad(indent_, out)
} else prevFields = true
if (indent.isEmpty) out.write(field.encodedName)
else out.write(field.prettyEncodedName)
out.write(if (indent eq None) field.encodedName else field.prettyEncodedName)
field.encoder.unsafeEncode(p, indent_, out)
}
}
Expand Down Expand Up @@ -636,17 +635,17 @@ sealed class JsonEncoderDerivation(config: JsonCodecConfiguration) extends Deriv
val indent_ = JsonEncoder.bump(indent)
JsonEncoder.pad(indent_, out)
out.write(encodedNames(idx))
if (indent.isEmpty) out.write(':')
if (indent eq None) out.write(':')
else out.write(" : ")
tcs(idx).unsafeEncode(casts(idx)(a), indent_, out)
tcs(idx).unsafeEncode(a, indent_, out)
JsonEncoder.pad(indent, out)
out.write('}')
}

override def toJsonAST(a: A): Either[String, Json] = {
var idx = 0
while (!casts(idx).isDefinedAt(a)) idx += 1
tcs(idx).toJsonAST(casts(idx)(a)).map(inner => new Json.Obj(Chunk(names(idx) -> inner)))
tcs(idx).toJsonAST(a).map(inner => new Json.Obj(Chunk(names(idx) -> inner)))
}
}
} else {
Expand All @@ -662,17 +661,17 @@ sealed class JsonEncoderDerivation(config: JsonCodecConfiguration) extends Deriv
val indent_ = JsonEncoder.bump(indent)
JsonEncoder.pad(indent_, out)
out.write(encodedHintFieldName)
if (indent.isEmpty) out.write(':')
if (indent eq None) out.write(':')
else out.write(" : ")
out.write(encodedNames(idx))
// whitespace is always off by 2 spaces at the end, probably not worth fixing
tcs(idx).unsafeEncode(casts(idx)(a), indent, new DeriveJsonEncoder.NestedWriter(out, indent_))
tcs(idx).unsafeEncode(a, indent, new DeriveJsonEncoder.NestedWriter(out, indent_))
}

override final def toJsonAST(a: A): Either[String, Json] = {
var idx = 0
while (!casts(idx).isDefinedAt(a)) idx += 1
tcs(idx).toJsonAST(casts(idx)(a)).flatMap {
tcs(idx).toJsonAST(a).flatMap {
case o: Json.Obj =>
val hintField = hintFieldName -> new Json.Str(names(idx))
new Right(new Json.Obj(hintField +: o.fields)) // hint field is always first
Expand Down

0 comments on commit 5bd5dd3

Please sign in to comment.