aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/pdsuidomain/formats/json/ListResponse.scala
blob: 3fbeac8c6a8b3db95c161b89efde44958f1596c3 (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
46
47
48
49
50
51
52
53
54
55
56
package xyz.driver.pdsuidomain.formats.json

import java.time.LocalDateTime

import xyz.driver.pdsuicommon.db.Pagination
import xyz.driver.pdsuicommon.json.Serialization.seqJsonFormat
import play.api.libs.functional.syntax._
import play.api.libs.json._

final case class ListResponse[+T](items: Seq[T], meta: ListResponse.Meta)

object ListResponse {

  final case class Meta(itemsCount: Int, pageNumber: Int, pageSize: Int, lastUpdate: Option[LocalDateTime])

  object Meta {
    def apply(itemsCount: Int, pagination: Pagination, lastUpdate: Option[LocalDateTime]): Meta = {
      Meta(itemsCount, pagination.pageNumber, pagination.pageSize, lastUpdate)
    }
  }

  private val listResponseMetaJsonReads: Reads[Meta] = {
    ((JsPath \ "itemsCount").read[Int] and
      (JsPath \ "pageNumber").read[Int] and
      (JsPath \ "pageSize").read[Int] and
      (JsPath \ "lastUpdate").readNullable[LocalDateTime]).apply {
      (itemsCount: Int, pageNumber: Int, pageSize: Int, lastUpdate: Option[LocalDateTime]) =>
        Meta(itemsCount, pageNumber, pageSize, lastUpdate)
    }
  }

  implicit val listResponseMetaJsonWrites: Writes[Meta] = (
    (JsPath \ "itemsCount").write[Int] and
      (JsPath \ "pageNumber").write[Int] and
      (JsPath \ "pageSize").write[Int] and
      (JsPath \ "lastUpdate").write[Option[LocalDateTime]]
  )(unlift(Meta.unapply))

  implicit val listResponseMetaJsonFormat: Format[Meta] = Format(
    listResponseMetaJsonReads,
    listResponseMetaJsonWrites
  )

  implicit def listResponseJsonWrites[T](implicit f: Writes[T]): Writes[ListResponse[T]] =
    (
      (JsPath \ "items").write[Seq[T]] and
        (JsPath \ "meta").write[Meta]
    )(unlift(ListResponse.unapply[T]))

  implicit def listResponseJsonFormat[T](implicit f: Format[T]): Format[ListResponse[T]] =
    (
      (JsPath \ "items").format(seqJsonFormat[T]) and
        (JsPath \ "meta").format[Meta]
    )(ListResponse.apply[T], unlift(ListResponse.unapply[T]))

}