Skip to content

Commit

Permalink
generate empty collections for missing fields
Browse files Browse the repository at this point in the history
  • Loading branch information
juliano committed Sep 17, 2024
1 parent 0ef6321 commit 0128a15
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1523,12 +1523,21 @@ object JsonCodec {
var i = 0
while (i < len) {
if (buffer(i) == null) {

if ((fields(i).optional || fields(i).transient) && fields(i).defaultValue.isDefined)
if ((fields(i).optional || fields(i).transient) && fields(i).defaultValue.isDefined) {
buffer(i) = fields(i).defaultValue.get
else
buffer(i) = schemaDecoder(schemas(i)).unsafeDecodeMissing(spans(i) :: trace)
} else {
val schema = fields(i).schema match {
case l @ Schema.Lazy(_) => l.schema
case _ => schemas(i)
}

schema match {
case collection: Schema.Collection[_, _] =>
buffer(i) = collection.empty
case _ =>
buffer(i) = schemaDecoder(schema).unsafeDecodeMissing(spans(i) :: trace)
}
}
}
i += 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,29 @@ object JsonCodecSpec extends ZIOSpecDefault {
)
}
),
suite("Missing collection fields")(
test("map") {
assertDecodes(
Schema[ListAndMap],
ListAndMap(Nil, Map.empty),
charSequenceToByteChunk("""{"list":[]}""")
)
},
test("list") {
assertDecodes(
Schema[ListAndMap],
ListAndMap(Nil, Map.empty),
charSequenceToByteChunk("""{"map":{}}""")
)
},
test("set") {
assertDecodes(
Schema[SetWrapper],
SetWrapper(Set.empty),
charSequenceToByteChunk("""{}""")
)
}
),
suite("zio.json.ast.Json decoding")(
test("Json.Obj") {
assertDecodes(
Expand Down Expand Up @@ -2172,6 +2195,12 @@ object JsonCodecSpec extends ZIOSpecDefault {
implicit lazy val schema: Schema[ListAndMapAndOption] = DeriveSchema.gen[ListAndMapAndOption]
}

final case class SetWrapper(set: Set[String])

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

final case class KeyWrapper(key: String)

object KeyWrapper {
Expand Down
10 changes: 9 additions & 1 deletion zio-schema/shared/src/main/scala/zio/schema/Schema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality {
sealed trait Collection[Col, Elem] extends Schema[Col] {
def fromChunk: Chunk[Elem] => Col
def toChunk: Col => Chunk[Elem]
def empty: Col
}

final case class Sequence[Col, Elem, I](
Expand All @@ -534,6 +535,7 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality {

override def toString: String = s"Sequence($elementSchema, $identity)"

override def empty: Col = Seq.empty[Elem].asInstanceOf[Col]
}

final case class Transform[A, B, I](
Expand Down Expand Up @@ -840,6 +842,7 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality {

override val toChunk: scala.collection.immutable.Map[K, V] => Chunk[(K, V)] = map => Chunk.fromIterable(map.toList)

override def empty: scala.collection.immutable.Map[K, V] = scala.collection.immutable.Map.empty[K, V]
}

final case class NonEmptyMap[K, V](
Expand Down Expand Up @@ -874,6 +877,8 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality {

override def makeAccessors(b: AccessorBuilder): b.Traversal[prelude.NonEmptyMap[K, V], (K, V)] =
b.makeTraversal(self, keySchema <*> valueSchema)

override def empty: prelude.NonEmptyMap[K, V] = throw new IllegalArgumentException(s"NonEmptySequence $identity cannot be empty")
}

final case class NonEmptySequence[Col, Elm, I](
Expand All @@ -900,6 +905,8 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality {
override def makeAccessors(b: AccessorBuilder): b.Traversal[Col, Elm] = b.makeTraversal(self, elementSchema)

override def toString: String = s"NonEmptySequence($elementSchema, $identity)"

override def empty: Col = throw new IllegalArgumentException(s"NonEmptySequence $identity cannot be empty")
}

final case class Set[A](elementSchema: Schema[A], override val annotations: Chunk[Any] = Chunk.empty)
Expand All @@ -923,6 +930,7 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality {

override val toChunk: scala.collection.immutable.Set[A] => Chunk[A] = Chunk.fromIterable(_)

override def empty: scala.collection.immutable.Set[A] = scala.collection.immutable.Set.empty[A]
}

final case class Dynamic(override val annotations: Chunk[Any] = Chunk.empty) extends Schema[DynamicValue] {
Expand Down Expand Up @@ -10240,4 +10248,4 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality {
type Field22 = F22
}
}
}
}

0 comments on commit 0128a15

Please sign in to comment.