Как создать декодер для любого типа с помощью Circe? - PullRequest
1 голос
/ 29 апреля 2020

Если вы ожидаете получить Json типа A или типа B (Either[A, B]), как вы могли бы написать для него декодер?

Например, давайте скажем, вы создаете клиент для внешнего API, который может ответить с некоторой ожидаемой структурой Json:

{
  "fieldA": "value",
  "fieldB": "value2"
}

или, если что-то не получится, он ответит объектом с полем error:

{
  "error": "Your request was wrong"
}

И затем вы хотите иметь экземпляр с любой из этих структур:

val response: String = // Response from the server 
val decodedValue =
  decode[Either[ErrorResponse, ExpectedResponse](response) // (...) <- What implicit to place here?

Как вы можете написать декодер для одной структуры ответа или другой?

1 Ответ

1 голос
/ 29 апреля 2020

Из Выпуск Circe 672 , вы можете написать обобщенный c декодер для 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
}

Примечание: Для этого подхода Вам все еще нужно неявно определить декодер для A и для B. В большинстве случаев достаточно использовать deriveDecoder.

...