You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

64 lines
2.2 KiB

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
}
}