如何使用 Circe 创建 Either 类型的解码器?

Cam*_*dro 4 scala circe

如果您期望收到类型A或类型B( Either[A, B]) 的 Json,您如何为其编写解码器?

例如,假设您正在为外部 API 构建一个客户端,该客户端可以使用一些预期的 Json 结构进行应答:

{
  "fieldA": "value",
  "fieldB": "value2"
}
Run Code Online (Sandbox Code Playgroud)

或者如果出现问题,它将使用带有字段的对象进行响应error

{
  "error": "Your request was wrong"
}
Run Code Online (Sandbox Code Playgroud)

然后你想要一个具有这些结构之一的实例:

{
  "fieldA": "value",
  "fieldB": "value2"
}
Run Code Online (Sandbox Code Playgroud)

如何为一种响应结构或另一种响应结构编写解码器?

Cam*_*dro 5

Circe 第 672 期开始,您可以通过以下方式为 Either 编写通用解码器:

implicit def eitherDecoder[A, B](implicit a: Decoder[A], b: Decoder[B]): Decoder[Either[A, B]] = {
  val left:  Decoder[Either[A, B]]= a.map(Left.apply)
  val right: Decoder[Either[A, B]]= b.map(Right.apply)
  left or right
}
Run Code Online (Sandbox Code Playgroud)

注意:对于这种方法,您仍然需要隐式定义A和 的解码器B。大多数情况下,使用deriveDecoder就足够了。