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