Alexis Hernandez
7 years ago
6 changed files with 119 additions and 0 deletions
@ -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) |
||||
|
} |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
package com.xsn.explorer.models.base |
||||
|
|
||||
|
case class FieldOrdering[+A](field: A, orderingCondition: OrderingCondition) |
@ -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 |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
package com.xsn.explorer.models.base |
||||
|
|
||||
|
case class OrderingQuery(string: String) extends AnyVal |
@ -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 |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue