Browse Source

server: Add FieldOrderingParser

scalafmt-draft
Alexis Hernandez 7 years ago
parent
commit
6f2b9f8aee
  1. 36
      server/app/com/xsn/explorer/errors/orderingErrors.scala
  2. 3
      server/app/com/xsn/explorer/models/base/FieldOrdering.scala
  3. 9
      server/app/com/xsn/explorer/models/base/OrderingCondition.scala
  4. 3
      server/app/com/xsn/explorer/models/base/OrderingQuery.scala
  5. 64
      server/app/com/xsn/explorer/parsers/FieldOrderingParser.scala
  6. 4
      server/conf/messages

36
server/app/com/xsn/explorer/errors/orderingErrors.scala

@ -0,0 +1,36 @@
package com.xsn.explorer.errors
import com.alexitc.playsonify.models.{FieldValidationError, InputValidationError, PublicError}
import play.api.i18n.{Lang, MessagesApi}
sealed trait OrderingError
case object UnknownOrderingFieldError extends OrderingError with InputValidationError {
override def toPublicErrorList(messagesApi: MessagesApi)(implicit lang: Lang): List[PublicError] = {
val message = messagesApi("error.ordering.unknownField")
val error = FieldValidationError("orderBy", message)
List(error)
}
}
case object InvalidOrderingConditionError extends OrderingError with InputValidationError {
override def toPublicErrorList(messagesApi: MessagesApi)(implicit lang: Lang): List[PublicError] = {
val message = messagesApi("error.ordering.unknownCondition")
val error = FieldValidationError("orderBy", message)
List(error)
}
}
case object InvalidOrderingError extends OrderingError with InputValidationError {
override def toPublicErrorList(messagesApi: MessagesApi)(implicit lang: Lang): List[PublicError] = {
val message = messagesApi("error.ordering.invalid")
val error = FieldValidationError("orderBy", message)
List(error)
}
}

3
server/app/com/xsn/explorer/models/base/FieldOrdering.scala

@ -0,0 +1,3 @@
package com.xsn.explorer.models.base
case class FieldOrdering[+A](field: A, orderingCondition: OrderingCondition)

9
server/app/com/xsn/explorer/models/base/OrderingCondition.scala

@ -0,0 +1,9 @@
package com.xsn.explorer.models.base
sealed trait OrderingCondition
object OrderingCondition {
case object AscendingOrder extends OrderingCondition
case object DescendingOrder extends OrderingCondition
}

3
server/app/com/xsn/explorer/models/base/OrderingQuery.scala

@ -0,0 +1,3 @@
package com.xsn.explorer.models.base
case class OrderingQuery(string: String) extends AnyVal

64
server/app/com/xsn/explorer/parsers/FieldOrderingParser.scala

@ -0,0 +1,64 @@
package com.xsn.explorer.parsers
import com.alexitc.playsonify.core.{ApplicationErrors, ApplicationResult}
import com.xsn.explorer.errors.{InvalidOrderingConditionError, InvalidOrderingError, UnknownOrderingFieldError}
import com.xsn.explorer.models.base.{FieldOrdering, OrderingCondition, OrderingQuery}
import org.scalactic._
trait FieldOrderingParser[+A] {
protected def parseField(unsafeField: String): Option[A]
protected def defaultField: A
protected def defaultOrderingCondition: OrderingCondition = OrderingCondition.AscendingOrder
/**
* Accepts values in the format field[:condition], being condition
* an optional argument allowing the these values:
* - asc: for ascending order.
* - desc: for descending order.
*
* The empty string is also accepted returning a default ordering.
*/
def from(orderByQuery: OrderingQuery): ApplicationResult[FieldOrdering[A]] = {
Option(orderByQuery.string)
.filter(_.nonEmpty)
.map { string => from(string.split(":")) }
.getOrElse {
val ordering = FieldOrdering(defaultField, defaultOrderingCondition)
Good(ordering)
}
}
private def from(parts: Seq[String]): FieldOrdering[A] Or ApplicationErrors = parts match {
case Seq(unsafeField) =>
for {
field <- getFieldResult(unsafeField)
} yield FieldOrdering(field, defaultOrderingCondition)
case Seq(unsafeField, unsafeOrderingCondition) =>
Accumulation.withGood(
getFieldResult(unsafeField),
getOrderingConditionResult(unsafeOrderingCondition)) { FieldOrdering.apply }
case _ =>
Bad(InvalidOrderingError).accumulating
}
private def getFieldResult(unsafeField: String) = {
val maybe = parseField(unsafeField)
Or.from(maybe, One(UnknownOrderingFieldError))
}
private def getOrderingConditionResult(unsafeOrderingCondition: String) = {
val maybe = parseOrderingCondition(unsafeOrderingCondition)
Or.from(maybe, One(InvalidOrderingConditionError))
}
protected def parseOrderingCondition(unsafeOrderingCondition: String): Option[OrderingCondition] = unsafeOrderingCondition match {
case "asc" => Some(OrderingCondition.AscendingOrder)
case "desc" => Some(OrderingCondition.DescendingOrder)
case _ => None
}
}

4
server/conf/messages

@ -12,3 +12,7 @@ error.block.notFound=Block not found
error.paginatedQuery.offset.invalid=Invalid offset, it should be a number greater or equal than 0
error.paginatedQuery.limit.invalid=Invalid limit, it should be a number between 1 and and {0}
error.ordering.unknownField=Unknown ordering field
error.ordering.unknownCondition=Unknown ordering condition
error.ordering.invalid=Invalid format

Loading…
Cancel
Save