diff options
author | vlad <vlad@driver.xyz> | 2017-06-27 17:13:02 -0700 |
---|---|---|
committer | vlad <vlad@driver.xyz> | 2017-06-27 17:13:02 -0700 |
commit | 5832f63b84d7388441d1200f2442dc1e9de0225c (patch) | |
tree | 32f63acdc920c14effc3d0d2822c05c125ad49e4 /src/main/scala/xyz/driver/pdsuicommon | |
parent | 9dd50590d4c8f8b9442d7c21ddd1def9dd453d5e (diff) | |
download | rest-query-5832f63b84d7388441d1200f2442dc1e9de0225c.tar.gz rest-query-5832f63b84d7388441d1200f2442dc1e9de0225c.tar.bz2 rest-query-5832f63b84d7388441d1200f2442dc1e9de0225c.zip |
All PDS UI domain models, API case classes, service traits and necessary utils moved to pdsui-commonv0.1.11
Diffstat (limited to 'src/main/scala/xyz/driver/pdsuicommon')
11 files changed, 149 insertions, 3 deletions
diff --git a/src/main/scala/xyz/driver/pdsuicommon/utils/Computation.scala b/src/main/scala/xyz/driver/pdsuicommon/computation/Computation.scala index 9e6f3bd..ad458de 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/utils/Computation.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/computation/Computation.scala @@ -1,4 +1,4 @@ -package xyz.driver.pdsuicommon.utils +package xyz.driver.pdsuicommon.computation import scala.concurrent.{ExecutionContext, Future} diff --git a/src/main/scala/xyz/driver/pdsuicommon/computation/FutureToComputationOps.scala b/src/main/scala/xyz/driver/pdsuicommon/computation/FutureToComputationOps.scala new file mode 100644 index 0000000..c5800dc --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/computation/FutureToComputationOps.scala @@ -0,0 +1,24 @@ +package xyz.driver.pdsuicommon.computation + +import xyz.driver.pdsuicommon.error.DomainError + +import scala.concurrent.{ExecutionContext, Future} + +final class FutureToComputationOps[T](val self: Future[T]) extends AnyVal { + + def handleDomainError[U, ER](f: PartialFunction[T, U]) + (implicit unsuitableToErrorsResponse: DomainError => ER, + ec: ExecutionContext): Future[Either[ER, U]] = { + self.map { + case x if f.isDefinedAt(x) => Right(f(x)) + case x: DomainError => Left(unsuitableToErrorsResponse(x)) + case x => throw new RuntimeException(s"Can not process $x") + } + } + + def toComputation[U, ER](f: PartialFunction[T, U]) + (implicit unsuitableToErrorsResponse: DomainError => ER, + ec: ExecutionContext): Computation[ER, U] = { + Computation(handleDomainError(f)) + } +} diff --git a/src/main/scala/xyz/driver/pdsuicommon/computation/Implicits.scala b/src/main/scala/xyz/driver/pdsuicommon/computation/Implicits.scala new file mode 100644 index 0000000..d5acc2d --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/computation/Implicits.scala @@ -0,0 +1,15 @@ +package xyz.driver.pdsuicommon.computation + +import scala.concurrent.Future +import scala.util.Try + +trait Implicits { + + implicit def futureToFutureComputationOps[T](self: Future[T]): FutureToComputationOps[T] = { + new FutureToComputationOps[T](self) + } + + implicit def tryToTryComputationOps[T](self: Try[T]): TryToComputationOps[T] = { + new TryToComputationOps[T](self) + } +} diff --git a/src/main/scala/xyz/driver/pdsuicommon/computation/TryToComputationOps.scala b/src/main/scala/xyz/driver/pdsuicommon/computation/TryToComputationOps.scala new file mode 100644 index 0000000..8282bc6 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/computation/TryToComputationOps.scala @@ -0,0 +1,15 @@ +package xyz.driver.pdsuicommon.computation + +import scala.concurrent.ExecutionContext +import scala.util.control.NonFatal +import scala.util.{Failure, Success, Try} + +final class TryToComputationOps[T](val self: Try[T]) extends AnyVal { + + def toComputation[ER](implicit exceptionToErrorResponse: Throwable => ER, + ec: ExecutionContext): Computation[ER, T] = self match { + case Success(x) => Computation.continue(x) + case Failure(NonFatal(e)) => Computation.abort(exceptionToErrorResponse(e)) + case Failure(e) => Computation.fail(e) + } +} diff --git a/src/main/scala/xyz/driver/pdsuicommon/domain/FuzzyValue.scala b/src/main/scala/xyz/driver/pdsuicommon/domain/FuzzyValue.scala index 4c6bf3f..4e98f40 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/domain/FuzzyValue.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/domain/FuzzyValue.scala @@ -15,4 +15,16 @@ object FuzzyValue { def fromBoolean(x: Boolean): FuzzyValue = if (x) Yes else No implicit def toPhiString(x: FuzzyValue): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass)) + + val fromString: PartialFunction[String, FuzzyValue] = { + case "Yes" => Yes + case "No" => No + case "Maybe" => Maybe + } + + def valueToString(x: FuzzyValue): String = x match { + case Yes => "Yes" + case No => "No" + case Maybe => "Maybe" + } } diff --git a/src/main/scala/xyz/driver/pdsuicommon/utils/JsonSerializer.scala b/src/main/scala/xyz/driver/pdsuicommon/json/JsonSerializer.scala index 8c8fd4e..a53f1dd 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/utils/JsonSerializer.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/json/JsonSerializer.scala @@ -1,4 +1,4 @@ -package xyz.driver.pdsuicommon.utils +package xyz.driver.pdsuicommon.json import java.text.SimpleDateFormat diff --git a/src/main/scala/xyz/driver/pdsuicommon/json/JsonValidationException.scala b/src/main/scala/xyz/driver/pdsuicommon/json/JsonValidationException.scala new file mode 100644 index 0000000..21750b4 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/json/JsonValidationException.scala @@ -0,0 +1,5 @@ +package xyz.driver.pdsuicommon.json + +import xyz.driver.pdsuicommon.validation.JsonValidationErrors + +class JsonValidationException(val errors: JsonValidationErrors) extends Exception diff --git a/src/main/scala/xyz/driver/pdsuicommon/json/Serialization.scala b/src/main/scala/xyz/driver/pdsuicommon/json/Serialization.scala new file mode 100644 index 0000000..a6d3ee9 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/json/Serialization.scala @@ -0,0 +1,42 @@ +package xyz.driver.pdsuicommon.json + +import java.net.URI + +import play.api.libs.functional.syntax._ +import play.api.libs.json._ +import xyz.driver.pdsuicommon.domain._ + +object Serialization { + + // @TODO Test and check all items in an array + private def seqJsonReads[T](implicit argFormat: Reads[T]): Reads[Seq[T]] = Reads { + case JsArray(xs) => JsSuccess(xs.map { x => argFormat.reads(x).get }) + case x => JsError(s"Expected JsArray, but got $x") + } + + private def seqJsonWrites[T](implicit argFormat: Writes[T]): Writes[Seq[T]] = Writes { xs => + JsArray(xs.map(argFormat.writes)) + } + + implicit def seqJsonFormat[T](implicit f: Format[T]): Format[Seq[T]] = Format(seqJsonReads[T], seqJsonWrites[T]) + + private val uriJsonReads: Reads[URI] = Reads.StringReads.map(URI.create) + private val uriJsonWrites: Writes[URI] = Writes(uri => JsString(uri.toString)) + implicit val uriJsonFormat: Format[URI] = Format(uriJsonReads, uriJsonWrites) + + private def uuidIdJsonReads[T]: Reads[UuidId[T]] = Reads.uuidReads.map(x => UuidId[T](x)) + private def uuidIdJsonWrites[T]: Writes[UuidId[T]] = Writes.UuidWrites.contramap(_.id) + implicit def uuidIdJsonFormat[T]: Format[UuidId[T]] = Format(uuidIdJsonReads, uuidIdJsonWrites) + + private def longIdJsonReads[T]: Reads[LongId[T]] = Reads.LongReads.map(x => LongId[T](x)) + private def longIdJsonWrites[T]: Writes[LongId[T]] = Writes.LongWrites.contramap(_.id) + implicit def longIdJsonFormat[T]: Format[LongId[T]] = Format(longIdJsonReads, longIdJsonWrites) + + private val emailJsonReads: Reads[Email] = Reads.email.map(Email.apply) + private val emailJsonWrites: Writes[Email] = Writes(email => JsString(email.value)) + implicit val emailJsonFormat: Format[Email] = Format(emailJsonReads, emailJsonWrites) + + private val passwordHashJsonReads: Reads[PasswordHash] = Reads.StringReads.map(hash => PasswordHash(hash.getBytes("UTF-8"))) + private val passwordHashJsonWrites: Writes[PasswordHash] = Writes(passwordHash => JsString(passwordHash.value.toString)) + implicit val passwordHashJsonFormat: Format[PasswordHash] = Format(passwordHashJsonReads, passwordHashJsonWrites) +} diff --git a/src/main/scala/xyz/driver/pdsuicommon/validation/AdditionalConstraints.scala b/src/main/scala/xyz/driver/pdsuicommon/validation/AdditionalConstraints.scala new file mode 100644 index 0000000..115163c --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/validation/AdditionalConstraints.scala @@ -0,0 +1,25 @@ +package xyz.driver.pdsuicommon.validation + +import org.davidbild.tristate.Tristate +import play.api.data.validation._ + +object AdditionalConstraints { + + val optionNonEmptyConstraint: Constraint[Option[Any]] = { + Constraint("option.nonEmpty") { + case Some(x) => Valid + case None => Invalid("is empty") + } + } + + val tristateSpecifiedConstraint: Constraint[Tristate[Any]] = { + Constraint("tristate.specified") { + case Tristate.Unspecified => Invalid("unspecified") + case _ => Valid + } + } + + val uuid: Constraint[String] = { + Constraints.pattern("""[\da-z]{8}-[\da-z]{4}-[\da-z]{4}-[\da-z]{4}-[\da-z]{12}""".r, "uuid", "invalid uuid") + } +} diff --git a/src/main/scala/xyz/driver/pdsuicommon/validation/Validators.scala b/src/main/scala/xyz/driver/pdsuicommon/validation/Validators.scala index fca726c..a41f87a 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/validation/Validators.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/validation/Validators.scala @@ -1,7 +1,7 @@ package xyz.driver.pdsuicommon.validation +import xyz.driver.pdsuicommon.json.JsonSerializer import xyz.driver.pdsuicommon.logging._ -import xyz.driver.pdsuicommon.utils.JsonSerializer import scala.util.control.NonFatal diff --git a/src/main/scala/xyz/driver/pdsuicommon/validation/package.scala b/src/main/scala/xyz/driver/pdsuicommon/validation/package.scala new file mode 100644 index 0000000..9a31a93 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/validation/package.scala @@ -0,0 +1,8 @@ +package xyz.driver.pdsuicommon + +import play.api.data.validation.{ValidationError => PlayValidationError} +import play.api.libs.json.JsPath + +package object validation { + type JsonValidationErrors = Seq[(JsPath, Seq[PlayValidationError])] +} |