aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/pdsuidomain/formats/json/listresponse.scala
blob: 1e359d689f53b619ef5730ed6e9aba0ccd741d21 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package xyz.driver.pdsuidomain.formats.json

import spray.json.DefaultJsonProtocol._
import spray.json._
import xyz.driver.pdsuidomain.ListResponse
import xyz.driver.pdsuidomain.formats.json.common._

object listresponse {
  private val itemsField = "items"
  private val metaField  = "meta"

  implicit val listResponseMetaFormat: RootJsonFormat[ListResponse.Meta] = jsonFormat4(ListResponse.Meta.apply)

  implicit def listResponseWriter[T: JsonWriter]: RootJsonWriter[ListResponse[T]] =
    new RootJsonWriter[ListResponse[T]] {
      override def write(listResponse: ListResponse[T]): JsValue = {
        JsObject(
          itemsField -> listResponse.items.map(_.toJson).toJson,
          metaField  -> listResponse.meta.toJson
        )
      }
    }

  implicit def listResponseReader[T: JsonReader]: RootJsonReader[ListResponse[T]] =
    new RootJsonReader[ListResponse[T]] {
      override def read(json: JsValue): ListResponse[T] = json match {
        case JsObject(fields) =>
          val items = fields
            .get(itemsField)
            .map {
              case JsArray(elements) => elements.map(_.convertTo[T])(collection.breakOut)
              case x                 => deserializationError(s"Expected Array as JsArray, but got $x")
            }
            .getOrElse(deserializationError(s"ListResponse json object does not contain `$itemsField` field: $json"))

          val meta = fields
            .get(metaField)
            .map(_.convertTo[ListResponse.Meta])
            .getOrElse(deserializationError(s"ListResponse json object does not contain `$metaField` field: $json"))

          ListResponse(items, meta)
        case _ => deserializationError(s"Expected ListResponse json object, but got $json")
      }
    }
}