Skip to content

Commit

Permalink
feat: support ListMap (#1177)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThijsBroersen authored Oct 20, 2024
1 parent e8b1b79 commit 7066a54
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 0 deletions.
4 changes: 4 additions & 0 deletions zio-json/shared/src/main/scala/zio/json/JsonCodec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ private[json] trait CodecLowPriority1 extends CodecLowPriority2 { this: JsonCode

implicit def sortedSet[A: Ordering: JsonEncoder: JsonDecoder]: JsonCodec[immutable.SortedSet[A]] =
JsonCodec(JsonEncoder.sortedSet[A], JsonDecoder.sortedSet[A])

implicit def listMap[K: JsonFieldEncoder: JsonFieldDecoder, V: JsonEncoder: JsonDecoder]
: JsonCodec[immutable.ListMap[K, V]] =
JsonCodec(JsonEncoder.listMap[K, V], JsonDecoder.listMap[K, V])
}

private[json] trait CodecLowPriority2 extends CodecLowPriority3 { this: JsonCodec.type =>
Expand Down
7 changes: 7 additions & 0 deletions zio-json/shared/src/main/scala/zio/json/JsonDecoder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,13 @@ private[json] trait DecoderLowPriority1 extends DecoderLowPriority2 {
def unsafeDecode(trace: List[JsonError], in: RetractReader): collection.SortedMap[K, V] =
keyValueBuilder(trace, in, collection.SortedMap.newBuilder[K, V])
}

implicit def listMap[K: JsonFieldDecoder, V: JsonDecoder]: JsonDecoder[immutable.ListMap[K, V]] =
new JsonDecoder[immutable.ListMap[K, V]] {

def unsafeDecode(trace: List[JsonError], in: RetractReader): immutable.ListMap[K, V] =
keyValueBuilder(trace, in, immutable.ListMap.newBuilder[K, V])
}
}

// We have a hierarchy of implicits for two reasons:
Expand Down
3 changes: 3 additions & 0 deletions zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ private[json] trait EncoderLowPriority1 extends EncoderLowPriority2 {

implicit def sortedMap[K: JsonFieldEncoder, V: JsonEncoder]: JsonEncoder[collection.SortedMap[K, V]] =
keyValueIterable[K, V, collection.SortedMap]

implicit def listMap[K: JsonFieldEncoder, V: JsonEncoder]: JsonEncoder[immutable.ListMap[K, V]] =
keyValueIterable[K, V, immutable.ListMap]
}

private[json] trait EncoderLowPriority2 extends EncoderLowPriority3 {
Expand Down
6 changes: 6 additions & 0 deletions zio-json/shared/src/test/scala/zio/json/CodecSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ object CodecSpec extends ZIOSpecDefault {

assert(jsonStr.fromJson[Map[String, Int]])(isRight(equalTo(expected)))
},
test("ListMap") {
val jsonStr = """{"5XL":3,"2XL":14,"XL":159}"""
val expected = collection.immutable.ListMap("5XL" -> 3, "2XL" -> 14, "XL" -> 159)

assert(jsonStr.fromJson[collection.immutable.ListMap[String, Int]])(isRight(equalTo(expected)))
},
test("zio.Chunk") {
val jsonStr = """["5XL","2XL","XL"]"""
val expected = Chunk("5XL", "2XL", "XL")
Expand Down
6 changes: 6 additions & 0 deletions zio-json/shared/src/test/scala/zio/json/DecoderSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,12 @@ object DecoderSpec extends ZIOSpecDefault {

assert(json.as[SortedMap[String, Int]])(isRight(equalTo(expected)))
},
test("ListMap") {
val json = Json.Obj("5XL" -> Json.Num(3), "2XL" -> Json.Num(14), "XL" -> Json.Num(159))
val expected = immutable.ListMap("5XL" -> 3, "2XL" -> 14, "XL" -> 159)

assert(json.as[immutable.ListMap[String, Int]])(isRight(equalTo(expected)))
},
test("Map, custom keys") {
val json = Json.Obj("1" -> Json.Str("a"), "2" -> Json.Str("b"))
val expected = Map(1 -> "a", 2 -> "b")
Expand Down
3 changes: 3 additions & 0 deletions zio-json/shared/src/test/scala/zio/json/EncoderSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ object EncoderSpec extends ZIOSpecDefault {
assert(Map("hello" -> "world").toJsonPretty)(equalTo("{\n \"hello\" : \"world\"\n}")) &&
assert(Map("hello" -> Some("world"), "goodbye" -> None).toJsonPretty)(
equalTo("{\n \"hello\" : \"world\"\n}")
) &&
assert(immutable.ListMap("hello" -> "world", "goodbye" -> "world").toJson)(
equalTo("""{"hello":"world","goodbye":"world"}""")
)
},
test("Map, custom keys") {
Expand Down

0 comments on commit 7066a54

Please sign in to comment.