Skip to content

Commit

Permalink
Add JsonCodec.Config.explicitNulls option (#740)
Browse files Browse the repository at this point in the history
  • Loading branch information
a-morales authored Sep 17, 2024
1 parent a5cec32 commit 0ef6321
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ import zio.{ Cause, Chunk, ChunkBuilder, ZIO, ZNothing }

object JsonCodec {

final case class Config(ignoreEmptyCollections: Boolean, treatStreamsAsArrays: Boolean = false)
final case class Config(
ignoreEmptyCollections: Boolean,
treatStreamsAsArrays: Boolean = false,
explicitNulls: Boolean = false
)

object Config {
val default: Config = Config(ignoreEmptyCollections = false)
Expand Down Expand Up @@ -1089,7 +1093,7 @@ object JsonCodec {
case e: Throwable => throw new RuntimeException(s"Failed to encode field '${s.name}' in $schema'", e)
}
val value = s.get(a)
if (!enc.isNothing(value) && !isEmptyOptionalValue(s, value, cfg)) {
if (!isEmptyOptionalValue(s, value, cfg) && (!enc.isNothing(value) || cfg.explicitNulls)) {
if (first)
first = false
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,34 +118,42 @@ object JsonCodecSpec extends ZIOSpecDefault {
suite("empty collections config")(
test("list empty") {
assertEncodesJson(
Schema[ListAndMap],
ListAndMap(Nil, Map("foo" -> 1)),
"""{"map":{"foo":1}}""",
JsonCodec.Config(ignoreEmptyCollections = true)
Schema[ListAndMapAndOption],
ListAndMapAndOption(Nil, Map("foo" -> 1), Some("foo")),
"""{"map":{"foo":1},"option":"foo"}""",
JsonCodec.Config(ignoreEmptyCollections = true, explicitNulls = false)
)
},
test("map empty") {
assertEncodesJson(
Schema[ListAndMap],
ListAndMap(List("foo"), Map.empty),
"""{"list":["foo"]}""",
JsonCodec.Config(ignoreEmptyCollections = true)
Schema[ListAndMapAndOption],
ListAndMapAndOption(List("foo"), Map.empty, Some("foo")),
"""{"list":["foo"],"option":"foo"}""",
JsonCodec.Config(ignoreEmptyCollections = true, explicitNulls = false)
)
},
test("option empty") {
assertEncodesJson(
Schema[ListAndMapAndOption],
ListAndMapAndOption(List("foo"), Map("foo" -> 1), None),
"""{"list":["foo"],"map":{"foo":1}}""",
JsonCodec.Config(ignoreEmptyCollections = true, explicitNulls = false)
)
},
test("all empty") {
assertEncodesJson(
Schema[ListAndMap],
ListAndMap(Nil, Map.empty),
Schema[ListAndMapAndOption],
ListAndMapAndOption(Nil, Map.empty, None),
"""{}""",
JsonCodec.Config(ignoreEmptyCollections = true)
JsonCodec.Config(ignoreEmptyCollections = true, explicitNulls = false)
)
},
test("all empty, but don't ignore empty collections") {
assertEncodesJson(
Schema[ListAndMap],
ListAndMap(Nil, Map.empty),
"""{"list":[],"map":{}}""",
JsonCodec.Config(ignoreEmptyCollections = false)
Schema[ListAndMapAndOption],
ListAndMapAndOption(Nil, Map.empty, None),
"""{"list":[],"map":{},"option":null}""",
JsonCodec.Config(ignoreEmptyCollections = false, explicitNulls = true)
)
}
),
Expand Down Expand Up @@ -1510,8 +1518,7 @@ object JsonCodecSpec extends ZIOSpecDefault {
Enumeration3(StringValue3("foo"))
) &> assertEncodesThenDecodes(
Schema[Enumeration3],
Enumeration3(StringValue3Multi("foo", "bar")),
print = true
Enumeration3(StringValue3Multi("foo", "bar"))
)
},
test("of case classes with discriminator") {
Expand Down Expand Up @@ -2159,10 +2166,10 @@ object JsonCodecSpec extends ZIOSpecDefault {
implicit lazy val schema: Schema[WithOptField] = DeriveSchema.gen[WithOptField]
}

final case class ListAndMap(list: List[String], map: Map[String, Int])
final case class ListAndMapAndOption(list: List[String], map: Map[String, Int], option: Option[String])

object ListAndMap {
implicit lazy val schema: Schema[ListAndMap] = DeriveSchema.gen[ListAndMap]
object ListAndMapAndOption {
implicit lazy val schema: Schema[ListAndMapAndOption] = DeriveSchema.gen[ListAndMapAndOption]
}

final case class KeyWrapper(key: String)
Expand Down

0 comments on commit 0ef6321

Please sign in to comment.