Skip to content

Commit

Permalink
feat: string-like field-decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
ThijsBroersen committed Jun 28, 2024
1 parent 78870bb commit a1102ca
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
12 changes: 11 additions & 1 deletion zio-json/shared/src/main/scala/zio/json/JsonFieldDecoder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ trait JsonFieldDecoder[+A] {
def unsafeDecodeField(trace: List[JsonError], in: String): A
}

object JsonFieldDecoder {
object JsonFieldDecoder extends LowPriorityJsonFieldDecoder {
def apply[A](implicit a: JsonFieldDecoder[A]): JsonFieldDecoder[A] = a

implicit val string: JsonFieldDecoder[String] = new JsonFieldDecoder[String] {
Expand All @@ -65,3 +65,13 @@ object JsonFieldDecoder {
}
}
}

private[json] trait LowPriorityJsonFieldDecoder {

def string: JsonFieldDecoder[String]

private def quotedString = string.map(raw => s""""$raw"""")

implicit def stringLike[T <: String: JsonDecoder]: JsonFieldDecoder[T] =
quotedString.mapOrFail(implicitly[JsonDecoder[T]].decodeJson)
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ object DerivedDecoderSpec extends ZIOSpecDefault {

assertTrue("""{"aOrB": "A", "optA": "A"}""".fromJson[Foo] == Right(Foo("A", Some("A")))) &&
assertTrue("""{"aOrB": "C"}""".fromJson[Foo] == Left(".aOrB(expected one of: A, B)"))
}
},
test("Derives and decodes for a custom map key string-based union type") {
case class Foo(aOrB: Map["A" | "B", Int]) derives JsonDecoder

assertTrue("""{"aOrB": {"A": 1, "B": 2}}""".fromJson[Foo] == Right(Foo(Map("A" -> 1, "B" -> 2)))) &&
assertTrue("""{"aOrB": {"C": 1}}""".fromJson[Foo] == Left(".aOrB.C((expected one of: A, B))"))
},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ object DerivedEncoderSpec extends ZIOSpecDefault {
case class Foo(aOrB: "A" | "B", optA: Option["A"]) derives JsonEncoder

assertTrue(Foo("A", Some("A")).toJson == """{"aOrB":"A","optA":"A"}""")
},
test("Derives and encodes for a custom map key string-based union type") {
case class Foo(aOrB: Map["A" | "B", Int]) derives JsonEncoder

assertTrue(Foo(Map("A" -> 1, "B" -> 2)).toJson == """{"aOrB":{"A":1,"B":2}}""")
}
)
}

0 comments on commit a1102ca

Please sign in to comment.