aboutsummaryrefslogblamecommitdiff
path: root/src/main/scala/xyz/driver/pdsuicommon/parsers/PaginationParser.scala
blob: a6a7fae4857f21d9f78f868ddc47c64b368933fa (plain) (tree)



























































                                                                                                                  
package xyz.driver.server.parsers

import xyz.driver.pdsuicommon.db.Pagination
import xyz.driver.server.parsers.errors.ParseQueryArgException
import play.api.data.validation._
import play.api.routing.sird.QueryString
import xyz.driver.pdsuicommon.validation.AdditionalConstraints

import scala.util.Try

object PaginationParser {

  private val oneQueryArgConstraint: Constraint[Seq[String]] = {
    Constraint("query.oneArg") {
      case Nil      => Valid
      case x +: Nil => Valid
      case xs =>
        Invalid(new ValidationError(Seq(s"must be one argument, but there are multiple: '${xs.mkString(", ")}'")))
    }
  }

  private val pageSizeCheckConstraint: Constraint[Seq[String]] = {
    Constraint("pagination.pageSize") { args =>
      oneQueryArgConstraint(args) match {
        case x: Invalid => x
        case Valid      => AdditionalConstraints.positivePrintedNumber(args.head)
      }
    }
  }

  private val pageNumberCheckConstraint: Constraint[Seq[String]] = {
    Constraint("pagination.pageNumber") { args =>
      oneQueryArgConstraint(args) match {
        case x: Invalid => x
        case Valid      => AdditionalConstraints.positivePrintedNumber(args.head)
      }
    }
  }

  def parse(queryString: QueryString): Try[Pagination] = Try {
    val rawPageSizes   = queryString.getOrElse("pageSize", Seq(Pagination.Default.pageSize.toString))
    val rawPageNumbers = queryString.getOrElse("pageNumber", Seq(Pagination.Default.pageNumber.toString))

    val validation = Seq(
      "pageSize"   -> pageSizeCheckConstraint(rawPageSizes),
      "pageNumber" -> pageNumberCheckConstraint(rawPageNumbers)
    )

    val validationErrors = validation.collect {
      case (fieldName, e: Invalid) => (fieldName, e.errors.mkString("; "))
    }

    if (validationErrors.isEmpty) {
      Pagination(Integer.parseInt(rawPageSizes.head), Integer.parseInt(rawPageNumbers.head))
    } else {
      throw new ParseQueryArgException(validationErrors: _*)
    }
  }

}