Revert "Reland #3670, i.e. refactorImplicits"
This reverts commit a5f64a22e2
.
This commit is contained in:
parent
790732735a
commit
f03213cbe2
|
@ -52,7 +52,7 @@ trait LilaSocket { self: LilaController =>
|
|||
}
|
||||
f(ctx).map { resultOrSocket =>
|
||||
resultOrSocket.right.map {
|
||||
case (readIn, writeOut) => (e: Enumerator[A], i: Iteratee[A, Unit]) => {
|
||||
case (readIn, writeOut) => (e, i) => {
|
||||
writeOut |>> i
|
||||
e &> Enumeratee.mapInput { in =>
|
||||
if (limiter(ip, 1)(true)) in
|
||||
|
@ -61,7 +61,6 @@ trait LilaSocket { self: LilaController =>
|
|||
Input.EOF
|
||||
}
|
||||
} |>> readIn
|
||||
()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ object Practice extends LilaController {
|
|||
FormFuResult(form) { err =>
|
||||
env.api.structure.get map { html.practice.config(_, err) }
|
||||
} { text =>
|
||||
~env.api.config.set(text).right.toOption >>-
|
||||
env.api.config.set(text).valueOr(_ => funit) >>-
|
||||
env.api.structure.clear >>
|
||||
Env.mod.logApi.practiceConfig(me.id) inject Redirect(routes.Practice.config)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,15 @@ import play.twirl.api.Html
|
|||
import lila.api.Env.{ current => apiEnv }
|
||||
|
||||
object Environment
|
||||
extends lila.Lilaisms
|
||||
extends scalaz.syntax.ToIdOps
|
||||
with scalaz.std.OptionInstances
|
||||
with scalaz.std.OptionFunctions
|
||||
with scalaz.std.StringInstances
|
||||
with scalaz.syntax.std.ToOptionIdOps
|
||||
with scalalib.OrnicarMonoid.Instances
|
||||
with scalalib.Zero.Instances
|
||||
with scalalib.OrnicarOption
|
||||
with lila.LilaSteroids
|
||||
with StringHelper
|
||||
with JsonHelper
|
||||
with AssetHelper
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package lila.common
|
||||
|
||||
import lila.common.PimpedJson._
|
||||
import play.api.libs.json.{ Json, OWrites }
|
||||
|
||||
case class LightUser(
|
||||
|
|
|
@ -1,75 +1,154 @@
|
|||
package lila
|
||||
|
||||
import scala.util.Try
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import ornicar.scalalib
|
||||
import org.joda.time.DateTime
|
||||
import com.typesafe.config.Config
|
||||
import play.api.libs.json.{ JsObject, JsValue }
|
||||
import lila.base._
|
||||
import ornicar.scalalib
|
||||
import ornicar.scalalib.Zero
|
||||
import scala.util.Try
|
||||
|
||||
trait Lilaisms
|
||||
extends LilaTypes
|
||||
|
||||
extends scalalib.Validation
|
||||
with scalalib.Common
|
||||
with scalalib.OrnicarNonEmptyList
|
||||
with scalalib.OrnicarOption
|
||||
with scalalib.OrnicarMonoids
|
||||
with scalalib.Regex
|
||||
with scalalib.Validation
|
||||
with scalalib.Zeros
|
||||
with scalalib.OrnicarMonoid.Instances
|
||||
with scalalib.Zero.Syntax
|
||||
with scalaz.std.ListFunctions
|
||||
with scalaz.std.ListInstances
|
||||
with scalaz.std.OptionFunctions
|
||||
with scalalib.Zero.Instances
|
||||
with scalalib.OrnicarOption
|
||||
with scalalib.OrnicarNonEmptyList
|
||||
|
||||
with scalaz.std.OptionInstances
|
||||
with scalaz.std.StringInstances
|
||||
with scalaz.std.TupleInstances
|
||||
with scalaz.syntax.std.ToListOps
|
||||
with scalaz.std.OptionFunctions
|
||||
with scalaz.syntax.std.ToOptionIdOps
|
||||
with scalaz.syntax.ToApplyOps
|
||||
with scalaz.syntax.ToEqualOps
|
||||
with scalaz.syntax.ToFunctorOps
|
||||
|
||||
with scalaz.std.ListInstances
|
||||
with scalaz.std.ListFunctions
|
||||
with scalaz.syntax.std.ToListOps
|
||||
|
||||
with scalaz.std.StringInstances
|
||||
|
||||
with scalaz.std.TupleInstances
|
||||
|
||||
with scalaz.syntax.ToIdOps
|
||||
with scalaz.syntax.ToEqualOps
|
||||
with scalaz.syntax.ToApplyOps
|
||||
with scalaz.syntax.ToValidationOps
|
||||
with scalaz.syntax.ToFunctorOps
|
||||
with scalaz.syntax.ToMonoidOps
|
||||
with scalaz.syntax.ToShowOps
|
||||
with scalaz.syntax.ToTraverseOps
|
||||
with scalaz.syntax.ToValidationOps {
|
||||
with scalaz.syntax.ToShowOps
|
||||
|
||||
@inline implicit def toPimpedFuture[A](f: Fu[A]) = new PimpedFuture(f)
|
||||
@inline implicit def toPimpedFutureBoolean(f: Fu[Boolean]) = new PimpedFutureBoolean(f)
|
||||
@inline implicit def toPimpedFutureOption[A](f: Fu[Option[A]]) = new PimpedFutureOption(f)
|
||||
@inline implicit def toPimpedFutureValid[A](f: Fu[Valid[A]]) = new PimpedFutureValid(f)
|
||||
@inline implicit def toPimpedTraversableFuture[A, M[X] <: TraversableOnce[X]](t: M[Fu[A]]) =
|
||||
new PimpedTraversableFuture(t)
|
||||
with LilaSteroids
|
||||
|
||||
@inline implicit def toPimpedJsObject(jo: JsObject) = new PimpedJsObject(jo)
|
||||
@inline implicit def toPimpedJsValue(jv: JsValue) = new PimpedJsValue(jv)
|
||||
trait LilaSteroids {
|
||||
import Wrappers._
|
||||
|
||||
@inline implicit def toPimpedBoolean(b: Boolean) = new PimpedBoolean(b)
|
||||
@inline implicit def toPimpedInt(i: Int) = new PimpedInt(i)
|
||||
@inline implicit def toPimpedLong(l: Long) = new PimpedLong(l)
|
||||
@inline implicit def toPimpedFloat(f: Float) = new PimpedFloat(f)
|
||||
@inline implicit def toPimpedDouble(d: Double) = new PimpedDouble(d)
|
||||
|
||||
@inline implicit def toPimpedTryList[A](l: List[Try[A]]) = new PimpedTryList(l)
|
||||
@inline implicit def toPimpedList[A](l: List[A]) = new PimpedList(l)
|
||||
@inline implicit def toPimpedSeq[A](l: List[A]) = new PimpedSeq(l)
|
||||
@inline implicit def toPimpedByteArray(ba: Array[Byte]) = new PimpedByteArray(ba)
|
||||
|
||||
@inline implicit def toPimpedOption[A](a: Option[A]) = new PimpedOption(a)
|
||||
@inline implicit def toPimpedString(s: String) = new PimpedString(s)
|
||||
@inline implicit def toPimpedConfig(c: Config) = new PimpedConfig(c)
|
||||
@inline implicit def toPimpedDateTime(d: DateTime) = new PimpedDateTime(d)
|
||||
@inline implicit def toPimpedValid[A](v: Valid[A]) = new PimpedValid(v)
|
||||
@inline implicit def toPimpedTry[A](t: Try[A]) = new PimpedTry(t)
|
||||
@inline implicit def toPimpedEither[A, B](e: Either[A, B]) = new PimpedEither(e)
|
||||
@inline implicit def toPimpedFiniteDuration(d: FiniteDuration) = new PimpedFiniteDuration(d)
|
||||
|
||||
@inline implicit def toPimpedActorSystem(a: akka.actor.ActorSystem) = new PimpedActorSystem(a)
|
||||
@inline implicit def toLilaPimpedOption[A](a: Option[A]) = new LilaPimpedOption(a)
|
||||
@inline implicit def toLilaPimpedTryList[A](l: List[Try[A]]) = new LilaPimpedTryList(l)
|
||||
@inline implicit def toLilaPimpedList[A](l: List[A]) = new LilaPimpedList(l)
|
||||
@inline implicit def toLilaPimpedSeq[A](l: List[A]) = new LilaPimpedSeq(l)
|
||||
@inline implicit def toLilaPimpedDateTime(d: DateTime) = new LilaPimpedDateTime(d)
|
||||
@inline implicit def toLilaPimpedBoolean(b: Boolean) = new LilaPimpedBoolean(b)
|
||||
@inline implicit def toLilaPimpedInt(i: Int) = new LilaPimpedInt(i)
|
||||
@inline implicit def toLilaPimpedFloat(f: Float) = new LilaPimpedFloat(f)
|
||||
@inline implicit def toLilaPimpedDouble(d: Double) = new LilaPimpedDouble(d)
|
||||
@inline implicit def toLilaPimpedByteArray(ba: Array[Byte]) = new LilaPimpedByteArray(ba)
|
||||
|
||||
implicit val dateTimeOrdering: Ordering[DateTime] = Ordering.fromLessThan(_ isBefore _)
|
||||
}
|
||||
|
||||
final class PimpedActorSystem(private val a: akka.actor.ActorSystem) extends AnyVal {
|
||||
def lilaBus = lila.common.Bus(a)
|
||||
}
|
||||
object Wrappers {
|
||||
final class LilaPimpedDateTime(private val date: DateTime) extends AnyVal {
|
||||
def getSeconds: Long = date.getMillis / 1000
|
||||
def getCentis: Long = date.getMillis / 10
|
||||
}
|
||||
|
||||
final class LilaPimpedTryList[A](private val list: List[Try[A]]) extends AnyVal {
|
||||
def sequence: Try[List[A]] = (Try(List[A]()) /: list) {
|
||||
(a, b) => a flatMap (c => b map (d => d :: c))
|
||||
} map (_.reverse)
|
||||
}
|
||||
|
||||
final class LilaPimpedList[A](private val list: List[A]) extends AnyVal {
|
||||
def sortLike[B](other: List[B], f: A => B): List[A] = list.sortWith {
|
||||
case (x, y) => other.indexOf(f(x)) < other.indexOf(f(y))
|
||||
}
|
||||
}
|
||||
|
||||
final class LilaPimpedSeq[A](private val seq: Seq[A]) extends AnyVal {
|
||||
def has(a: A) = seq contains a
|
||||
}
|
||||
|
||||
/*
|
||||
* Replaces scalaz boolean ops
|
||||
* so ?? works on Zero and not Monoid
|
||||
*/
|
||||
final class LilaPimpedBoolean(private val self: Boolean) extends AnyVal {
|
||||
|
||||
def ??[A](a: => A)(implicit z: Zero[A]): A = if (self) a else Zero[A].zero
|
||||
|
||||
def !(f: => Unit) = if (self) f
|
||||
|
||||
def fold[A](t: => A, f: => A): A = if (self) t else f
|
||||
|
||||
def ?[X](t: => X) = new { def |(f: => X) = if (self) t else f }
|
||||
|
||||
def option[A](a: => A): Option[A] = if (self) Some(a) else None
|
||||
}
|
||||
|
||||
final class LilaPimpedInt(private val self: Int) extends AnyVal {
|
||||
|
||||
def atLeast(bottomValue: Int): Int = self max bottomValue
|
||||
|
||||
def atMost(topValue: Int): Int = self min topValue
|
||||
}
|
||||
|
||||
final class LilaPimpedFloat(private val self: Float) extends AnyVal {
|
||||
|
||||
def atLeast(bottomValue: Float): Float = self max bottomValue
|
||||
|
||||
def atMost(topValue: Float): Float = self min topValue
|
||||
}
|
||||
|
||||
final class LilaPimpedDouble(private val self: Double) extends AnyVal {
|
||||
|
||||
def atLeast(bottomValue: Double): Double = self max bottomValue
|
||||
|
||||
def atMost(topValue: Double): Double = self min topValue
|
||||
}
|
||||
|
||||
final class LilaPimpedByteArray(private val self: Array[Byte]) extends AnyVal {
|
||||
def toBase64 = java.util.Base64.getEncoder.encodeToString(self)
|
||||
}
|
||||
|
||||
/*
|
||||
* Replaces scalaz option ops
|
||||
* so ~ works on Zero and not Monoid
|
||||
*/
|
||||
final class LilaPimpedOption[A](private val self: Option[A]) extends AnyVal {
|
||||
|
||||
import scalaz.std.{ option => o }
|
||||
|
||||
def fold[X](some: A => X, none: => X): X = self match {
|
||||
case None => none
|
||||
case Some(a) => some(a)
|
||||
}
|
||||
|
||||
def |(a: => A): A = self getOrElse a
|
||||
|
||||
def unary_~(implicit z: Zero[A]): A = self getOrElse z.zero
|
||||
def orDefault(implicit z: Zero[A]): A = self getOrElse z.zero
|
||||
|
||||
def toSuccess[E](e: => E): scalaz.Validation[E, A] = o.toSuccess(self)(e)
|
||||
|
||||
def toFailure[B](b: => B): scalaz.Validation[A, B] = o.toFailure(self)(b)
|
||||
|
||||
def toTry(err: => Exception): Try[A] =
|
||||
self.fold[Try[A]](scala.util.Failure(err))(scala.util.Success.apply)
|
||||
|
||||
def err(message: => String): A = self.getOrElse(sys.error(message))
|
||||
|
||||
def ifNone(n: => Unit): Unit = if (self.isEmpty) n
|
||||
|
||||
def has(a: A) = self contains a
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,22 @@
|
|||
package lila
|
||||
|
||||
import scala.util.Try
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration, MILLISECONDS }
|
||||
import scala.concurrent.Future
|
||||
|
||||
import ornicar.scalalib
|
||||
import scalaz.{ Monad, Monoid, OptionT, ~> }
|
||||
|
||||
trait PackageObject extends Lilaisms {
|
||||
implicit val playExecutionContext = play.api.libs.concurrent.Execution.defaultContext
|
||||
trait PackageObject extends Lilaisms with WithFuture {
|
||||
|
||||
// case object Key(value: String) extends AnyVal with StringValue
|
||||
trait StringValue extends Any {
|
||||
def value: String
|
||||
override def toString = value
|
||||
}
|
||||
trait IntValue extends Any {
|
||||
def value: Int
|
||||
override def toString = value.toString
|
||||
}
|
||||
|
||||
def !![A](msg: String): Valid[A] = msg.failureNel[A]
|
||||
|
||||
|
@ -20,31 +31,52 @@ trait PackageObject extends Lilaisms {
|
|||
def apply[A](a: M[Option[A]]) = new OptionT[M, A](a)
|
||||
}
|
||||
|
||||
implicit def fuMonoid[A: Monoid]: Monoid[Fu[A]] =
|
||||
Monoid.instance((x, y) => x zip y map {
|
||||
case (a, b) => a ⊹ b
|
||||
}, fuccess(∅[A]))
|
||||
|
||||
implicit val monadFu = new Monad[Fu] {
|
||||
override def map[A, B](fa: Fu[A])(f: A => B) = fa map f
|
||||
def point[A](a: => A) = fuccess(a)
|
||||
def bind[A, B](fa: Fu[A])(f: A => Fu[B]) = fa flatMap f
|
||||
}
|
||||
|
||||
type ~[+A, +B] = Tuple2[A, B]
|
||||
object ~ {
|
||||
def apply[A, B](x: A, y: B) = Tuple2(x, y)
|
||||
def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
|
||||
}
|
||||
|
||||
def parseIntOption(str: String): Option[Int] =
|
||||
Try(java.lang.Integer.parseInt(str)).toOption
|
||||
implicit final class LilaPimpedString(s: String) {
|
||||
|
||||
def parseFloatOption(str: String): Option[Float] =
|
||||
Try(java.lang.Float.parseFloat(str)).toOption
|
||||
def boot[A](v: => A): A = lila.common.Chronometer.syncEffect(v) { lap =>
|
||||
lila.log.boot.info(s"${lap.millis}ms $s")
|
||||
}
|
||||
}
|
||||
|
||||
def parseLongOption(str: String): Option[Long] =
|
||||
Try(java.lang.Long.parseLong(str)).toOption
|
||||
implicit final class LilaPimpedValid[A](v: Valid[A]) {
|
||||
|
||||
def future: Fu[A] = v fold (errs => fufail(errs.shows), fuccess)
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedTry[A](v: scala.util.Try[A]) {
|
||||
|
||||
def fold[B](fe: Exception => B, fa: A => B): B = v match {
|
||||
case scala.util.Failure(e: Exception) => fe(e)
|
||||
case scala.util.Failure(e) => throw e
|
||||
case scala.util.Success(a) => fa(a)
|
||||
}
|
||||
|
||||
def future: Fu[A] = fold(Future.failed, fuccess)
|
||||
}
|
||||
|
||||
def parseIntOption(str: String): Option[Int] = try {
|
||||
Some(java.lang.Integer.parseInt(str))
|
||||
} catch {
|
||||
case e: NumberFormatException => None
|
||||
}
|
||||
|
||||
def parseFloatOption(str: String): Option[Float] = try {
|
||||
Some(java.lang.Float.parseFloat(str))
|
||||
} catch {
|
||||
case e: NumberFormatException => None
|
||||
}
|
||||
|
||||
def parseLongOption(str: String): Option[Long] = try {
|
||||
Some(java.lang.Long.parseLong(str))
|
||||
} catch {
|
||||
case e: NumberFormatException => None
|
||||
}
|
||||
|
||||
def intBox(in: Range.Inclusive)(v: Int): Int =
|
||||
math.max(in.start, math.min(v, in.end))
|
||||
|
@ -55,6 +87,110 @@ trait PackageObject extends Lilaisms {
|
|||
def doubleBox(in: Range.Inclusive)(v: Double): Double =
|
||||
math.max(in.start, math.min(v, in.end))
|
||||
|
||||
import play.api.libs.json._
|
||||
import scalalib.Zero
|
||||
|
||||
implicit def playExecutionContext = play.api.libs.concurrent.Execution.defaultContext
|
||||
val directEC = lila.PimpedFuture.DirectExecutionContext
|
||||
|
||||
implicit val LilaFutureMonad = new Monad[Fu] {
|
||||
override def map[A, B](fa: Fu[A])(f: A => B) = fa map f
|
||||
def point[A](a: => A) = fuccess(a)
|
||||
def bind[A, B](fa: Fu[A])(f: A => Fu[B]) = fa flatMap f
|
||||
}
|
||||
|
||||
implicit def LilaFuMonoid[A: Monoid]: Monoid[Fu[A]] =
|
||||
Monoid.instance((x, y) => x zip y map {
|
||||
case (a, b) => a ⊹ b
|
||||
}, fuccess(∅[A]))
|
||||
|
||||
implicit def LilaFuZero[A: Zero]: Zero[Fu[A]] =
|
||||
Zero.instance(fuccess(zero[A]))
|
||||
|
||||
implicit val LilaJsObjectZero: Zero[JsObject] =
|
||||
Zero.instance(JsObject(Seq.empty))
|
||||
|
||||
implicit def LilaJsResultZero[A]: Zero[JsResult[A]] =
|
||||
Zero.instance(JsError(Seq.empty))
|
||||
|
||||
implicit final class LilaTraversableFuture[A, M[X] <: TraversableOnce[X]](t: M[Fu[A]]) {
|
||||
|
||||
def sequenceFu(implicit cbf: scala.collection.generic.CanBuildFrom[M[Fu[A]], A, M[A]]) =
|
||||
Future sequence t
|
||||
}
|
||||
|
||||
implicit def toPimpedConfig(c: com.typesafe.config.Config) = new common.LilaPimpedConfig(c)
|
||||
|
||||
implicit def LilaPimpedFuture[A](fua: Fu[A]): PimpedFuture.LilaPimpedFuture[A] =
|
||||
new PimpedFuture.LilaPimpedFuture(fua)
|
||||
|
||||
implicit final class LilaPimpedFutureZero[A: Zero](fua: Fu[A]) {
|
||||
|
||||
def nevermind: Fu[A] = fua recover {
|
||||
case e: lila.base.LilaException => zero[A]
|
||||
case e: java.util.concurrent.TimeoutException => zero[A]
|
||||
case e: Exception =>
|
||||
lila.log("common").warn("Future.nevermind", e)
|
||||
zero[A]
|
||||
}
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedFutureOption[A](fua: Fu[Option[A]]) {
|
||||
|
||||
def flatten(msg: => String): Fu[A] = fua flatMap {
|
||||
_.fold[Fu[A]](fufail(msg))(fuccess(_))
|
||||
}
|
||||
|
||||
def orElse(other: => Fu[Option[A]]): Fu[Option[A]] = fua flatMap {
|
||||
_.fold(other) { x => fuccess(x.some) }
|
||||
}
|
||||
|
||||
def getOrElse(other: => Fu[A]): Fu[A] = fua flatMap { _.fold(other)(fuccess) }
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedFutureValid[A](fua: Fu[Valid[A]]) {
|
||||
|
||||
def flatten: Fu[A] = fua flatMap { _.fold[Fu[A]](fufail(_), fuccess(_)) }
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedFutureBoolean(fua: Fu[Boolean]) {
|
||||
|
||||
def >>&(fub: => Fu[Boolean]): Fu[Boolean] =
|
||||
fua flatMap { _.fold(fub, fuccess(false)) }
|
||||
|
||||
def >>|(fub: => Fu[Boolean]): Fu[Boolean] =
|
||||
fua flatMap { _.fold(fuccess(true), fub) }
|
||||
|
||||
def unary_! = fua dmap (!_)
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedBooleanWithFuture(self: Boolean) {
|
||||
|
||||
def optionFu[A](v: => Fu[A]): Fu[Option[A]] = if (self) v map (_.some) else fuccess(none)
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedActorSystem(self: akka.actor.ActorSystem) {
|
||||
|
||||
def lilaBus = lila.common.Bus(self)
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedFiniteDuration(self: FiniteDuration) {
|
||||
|
||||
def toCentis = chess.Centis {
|
||||
// divide by Double, then round, to avoid rounding issues with just `/10`!
|
||||
math.round {
|
||||
if (self.unit eq MILLISECONDS) self.length / 10d
|
||||
else self.toMillis / 10d
|
||||
}
|
||||
}
|
||||
|
||||
def abs = if (self.length < 0) -self else self
|
||||
}
|
||||
|
||||
implicit val LilaFiniteDurationZero: Zero[FiniteDuration] = Zero.instance(Duration.Zero)
|
||||
|
||||
implicit val LilaCentisZero: Zero[chess.Centis] = Zero instance chess.Centis(0)
|
||||
|
||||
object makeTimeout {
|
||||
|
||||
import akka.util.Timeout
|
||||
|
@ -69,4 +205,16 @@ trait PackageObject extends Lilaisms {
|
|||
def seconds(s: Int): Timeout = Timeout(s.seconds)
|
||||
def minutes(m: Int): Timeout = Timeout(m.minutes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait WithFuture extends scalalib.Validation {
|
||||
|
||||
type Fu[+A] = Future[A]
|
||||
type Funit = Fu[Unit]
|
||||
|
||||
def fuccess[A](a: A) = Future successful a
|
||||
def fufail[A <: Throwable, B](a: A): Fu[B] = Future failed a
|
||||
def fufail[A](a: String): Fu[A] = fufail(base.LilaException(a))
|
||||
def fufail[A](a: Failures): Fu[A] = fufail(base.LilaException(a))
|
||||
val funit = fuccess(())
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package lila.base
|
||||
package lila.common
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import java.util.concurrent.TimeUnit
|
|
@ -4,10 +4,9 @@ import play.api.libs.json._
|
|||
|
||||
object PimpedJson {
|
||||
|
||||
def anyValWriter[O, A: Writes](f: O => A) = Writes[O] { o =>
|
||||
def anyValWriter[O, A: Writes](f: O => A): Writes[O] = Writes[O] { o =>
|
||||
Json toJson f(o)
|
||||
}
|
||||
|
||||
def intAnyValWriter[O](f: O => Int): Writes[O] = anyValWriter[O, Int](f)
|
||||
def stringAnyValWriter[O](f: O => String): Writes[O] = anyValWriter[O, String](f)
|
||||
|
||||
|
@ -15,4 +14,85 @@ object PimpedJson {
|
|||
def intIsoWriter[O](iso: Iso[Int, O]): Writes[O] = anyValWriter[O, Int](iso.to)
|
||||
|
||||
def stringIsoReader[O](iso: Iso[String, O]): Reads[O] = Reads.of[String] map iso.from
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedJsObject(val js: JsObject) extends AnyVal {
|
||||
|
||||
def str(key: String): Option[String] =
|
||||
(js \ key).asOpt[String]
|
||||
|
||||
def int(key: String): Option[Int] =
|
||||
(js \ key).asOpt[Int]
|
||||
|
||||
def long(key: String): Option[Long] =
|
||||
(js \ key).asOpt[Long]
|
||||
|
||||
def boolean(key: String): Option[Boolean] =
|
||||
(js \ key).asOpt[Boolean]
|
||||
|
||||
def obj(key: String): Option[JsObject] =
|
||||
(js \ key).asOpt[JsObject]
|
||||
|
||||
def arr(key: String): Option[JsArray] =
|
||||
(js \ key).asOpt[JsArray]
|
||||
|
||||
def arrAs[A](key: String)(as: JsValue => Option[A]): Option[List[A]] =
|
||||
arr(key) map { j =>
|
||||
(j.value.map(as)(scala.collection.breakOut): List[Option[A]]).flatten
|
||||
}
|
||||
|
||||
def ints(key: String): Option[List[Int]] = arrAs(key)(_.asOpt[Int])
|
||||
|
||||
def strs(key: String): Option[List[String]] = arrAs(key)(_.asOpt[String])
|
||||
|
||||
def objs(key: String): Option[List[JsObject]] = arrAs(key)(_.asOpt[JsObject])
|
||||
|
||||
def get[A: Reads](key: String): Option[A] =
|
||||
(js \ key).asOpt[A]
|
||||
|
||||
def noNull = JsObject {
|
||||
js.fields collect {
|
||||
case (key, value) if value != JsNull => key -> value
|
||||
}
|
||||
}
|
||||
|
||||
def add(pair: (String, Boolean)): JsObject =
|
||||
if (pair._2) js + (pair._1 -> JsBoolean(true))
|
||||
else js
|
||||
|
||||
def add[A: Writes](pair: (String, Option[A])): JsObject =
|
||||
pair._2.fold(js) { a => js + (pair._1 -> Json.toJson(a)) }
|
||||
}
|
||||
|
||||
implicit final class LilaPimpedJsValue(val js: JsValue) extends AnyVal {
|
||||
|
||||
def str(key: String): Option[String] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[String]
|
||||
}
|
||||
|
||||
def int(key: String): Option[Int] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[Int]
|
||||
}
|
||||
|
||||
def long(key: String): Option[Long] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[Long]
|
||||
}
|
||||
|
||||
def boolean(key: String): Option[Boolean] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[Boolean]
|
||||
}
|
||||
|
||||
def obj(key: String): Option[JsObject] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[JsObject]
|
||||
}
|
||||
|
||||
def arr(key: String): Option[JsArray] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[JsArray]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package lila.base
|
||||
|
||||
import ornicar.scalalib.ValidTypes._
|
||||
import ornicar.scalalib
|
||||
|
||||
trait LilaException extends Exception {
|
||||
val message: String
|
||||
|
@ -9,9 +9,10 @@ trait LilaException extends Exception {
|
|||
override def toString = message
|
||||
}
|
||||
|
||||
object LilaException extends scalaz.syntax.ToShowOps {
|
||||
object LilaException extends scalalib.Validation
|
||||
with scalaz.syntax.ToShowOps {
|
||||
|
||||
def apply(msg: String) = new LilaException {
|
||||
def apply(msg: String): LilaException = new LilaException {
|
||||
val message = msg
|
||||
}
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
package lila.base
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
import scala.concurrent.Future
|
||||
|
||||
import org.joda.time.DateTime
|
||||
import ornicar.scalalib.{ Zero, ValidTypes }
|
||||
import play.api.libs.json.{ JsObject, JsError }
|
||||
|
||||
trait LilaTypes extends ValidTypes {
|
||||
|
||||
trait StringValue extends Any {
|
||||
def value: String
|
||||
override def toString = value
|
||||
}
|
||||
trait IntValue extends Any {
|
||||
def value: Int
|
||||
override def toString = value.toString
|
||||
}
|
||||
|
||||
type Fu[A] = Future[A]
|
||||
type Funit = Fu[Unit]
|
||||
|
||||
@inline def fuccess[A](a: A): Fu[A] = Future.successful(a)
|
||||
def fufail[X](t: Throwable): Fu[X] = Future.failed(t)
|
||||
def fufail[X](s: String): Fu[X] = fufail(LilaException(s))
|
||||
def fufail[X](f: Failures): Fu[X] = fufail(LilaException(f))
|
||||
val funit = fuccess(())
|
||||
|
||||
implicit def fuZero[A](implicit az: Zero[A]) = new Zero[Fu[A]] {
|
||||
def zero = fuccess(az.zero)
|
||||
}
|
||||
|
||||
implicit val durationZero: Zero[Duration] = Zero.instance(Duration.Zero)
|
||||
implicit val jsObjectZero = Zero.instance(JsObject(Seq.empty))
|
||||
implicit val jsResultZero = Zero.instance(JsError(Seq.empty))
|
||||
|
||||
implicit val dateTimeOrdering: Ordering[DateTime] = Ordering.fromLessThan(_ isBefore _)
|
||||
}
|
||||
|
||||
object LilaTypes extends LilaTypes
|
|
@ -1,176 +0,0 @@
|
|||
package lila.base
|
||||
|
||||
import play.api.libs.concurrent.Execution.Implicits._
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ Future, ExecutionContext }
|
||||
import LilaTypes._
|
||||
import ornicar.scalalib.Zero
|
||||
|
||||
object DirectExecutionContext extends ExecutionContext {
|
||||
override def execute(command: Runnable): Unit = command.run()
|
||||
override def reportFailure(cause: Throwable): Unit =
|
||||
throw new IllegalStateException("lila DirectExecutionContext failure", cause)
|
||||
}
|
||||
|
||||
final class PimpedFuture[A](private val fua: Fu[A]) extends AnyVal {
|
||||
private type Fu[A] = Future[A]
|
||||
|
||||
def dmap[B](f: A => B): Fu[B] = fua.map(f)(DirectExecutionContext)
|
||||
def dforeach[B](f: A => Unit): Unit = fua.foreach(f)(DirectExecutionContext)
|
||||
|
||||
def >>-(sideEffect: => Unit): Fu[A] = fua andThen {
|
||||
case _ => sideEffect
|
||||
}
|
||||
|
||||
def >>[B](fub: => Fu[B]): Fu[B] = fua flatMap (_ => fub)
|
||||
|
||||
def void: Fu[Unit] = fua.map(_ => ())(DirectExecutionContext)
|
||||
|
||||
def inject[B](b: => B): Fu[B] = fua.map(_ => b)(DirectExecutionContext)
|
||||
|
||||
def injectAnyway[B](b: => B): Fu[B] = fold(_ => b, _ => b)
|
||||
|
||||
def effectFold(fail: Exception => Unit, succ: A => Unit) {
|
||||
fua onComplete {
|
||||
case scala.util.Failure(e: Exception) => fail(e)
|
||||
case scala.util.Failure(e) => throw e // Throwables
|
||||
case scala.util.Success(e) => succ(e)
|
||||
}
|
||||
}
|
||||
|
||||
def fold[B](fail: Exception => B, succ: A => B): Fu[B] =
|
||||
fua map succ recover { case e: Exception => fail(e) }
|
||||
|
||||
def flatFold[B](fail: Exception => Fu[B], succ: A => Fu[B]): Fu[B] =
|
||||
fua flatMap succ recoverWith { case e: Exception => fail(e) }
|
||||
|
||||
def logFailure(logger: => lila.log.Logger, msg: Exception => String): Fu[A] =
|
||||
addFailureEffect { e => logger.warn(msg(e), e) }
|
||||
def logFailure(logger: => lila.log.Logger): Fu[A] = logFailure(logger, _.toString)
|
||||
|
||||
def addFailureEffect(effect: Exception => Unit) = {
|
||||
fua onFailure {
|
||||
case e: Exception => effect(e)
|
||||
}
|
||||
fua
|
||||
}
|
||||
|
||||
def addEffect(effect: A => Unit): Fu[A] = {
|
||||
fua foreach effect
|
||||
fua
|
||||
}
|
||||
|
||||
def addEffects(fail: Exception => Unit, succ: A => Unit): Fu[A] = {
|
||||
fua onComplete {
|
||||
case scala.util.Failure(e: Exception) => fail(e)
|
||||
case scala.util.Failure(e) => throw e // Throwables
|
||||
case scala.util.Success(e) => succ(e)
|
||||
}
|
||||
fua
|
||||
}
|
||||
|
||||
def addEffectAnyway(inAnyCase: => Unit): Fu[A] = {
|
||||
fua onComplete {
|
||||
case _ => inAnyCase
|
||||
}
|
||||
fua
|
||||
}
|
||||
|
||||
def mapFailure(f: Exception => Exception) = fua recover {
|
||||
case cause: Exception => throw f(cause)
|
||||
}
|
||||
|
||||
def prefixFailure(p: => String) = mapFailure { e =>
|
||||
LilaException(s"$p ${e.getMessage}")
|
||||
}
|
||||
|
||||
def thenPp: Fu[A] = {
|
||||
effectFold(
|
||||
e => println("[failure] " + e),
|
||||
a => println("[success] " + a)
|
||||
)
|
||||
fua
|
||||
}
|
||||
|
||||
def thenPp(msg: String): Fu[A] = {
|
||||
effectFold(
|
||||
e => println(s"[$msg] [failure] $e"),
|
||||
a => println(s"[$msg] [success] $a")
|
||||
)
|
||||
fua
|
||||
}
|
||||
|
||||
def await(duration: FiniteDuration): A =
|
||||
scala.concurrent.Await.result(fua, duration)
|
||||
|
||||
def awaitOrElse(duration: FiniteDuration, default: => A): A = try {
|
||||
scala.concurrent.Await.result(fua, duration)
|
||||
} catch {
|
||||
case _: Exception => default
|
||||
}
|
||||
|
||||
def awaitSeconds(seconds: Int): A =
|
||||
await(seconds.seconds)
|
||||
|
||||
def withTimeout(duration: FiniteDuration, error: => Throwable)(implicit system: akka.actor.ActorSystem): Fu[A] = {
|
||||
Future firstCompletedOf Seq(
|
||||
fua,
|
||||
akka.pattern.after(duration, system.scheduler)(Future failed error)
|
||||
)
|
||||
}
|
||||
|
||||
def withTimeoutDefault(duration: FiniteDuration, default: => A)(implicit system: akka.actor.ActorSystem): Fu[A] = {
|
||||
Future firstCompletedOf Seq(
|
||||
fua,
|
||||
akka.pattern.after(duration, system.scheduler)(Future(default))
|
||||
)
|
||||
}
|
||||
|
||||
def chronometer = lila.common.Chronometer(fua)
|
||||
|
||||
def mon(path: lila.mon.RecPath) = chronometer.mon(path).result
|
||||
|
||||
def nevermind(implicit z: Zero[A]): Fu[A] = fua recover {
|
||||
case e: LilaException => z.zero
|
||||
case e: java.util.concurrent.TimeoutException => z.zero
|
||||
case e: Exception =>
|
||||
lila.log("common").warn("Future.nevermind", e)
|
||||
z.zero
|
||||
}
|
||||
}
|
||||
|
||||
final class PimpedFutureBoolean(private val fua: Fu[Boolean]) extends AnyVal {
|
||||
|
||||
def >>&(fub: => Fu[Boolean]): Fu[Boolean] =
|
||||
fua flatMap { if (_) fub else fuccess(false) }
|
||||
|
||||
def >>|(fub: => Fu[Boolean]): Fu[Boolean] =
|
||||
fua flatMap { if (_) fuccess(true) else fub }
|
||||
|
||||
def unary_! = fua.map { !_ }(DirectExecutionContext)
|
||||
}
|
||||
|
||||
final class PimpedFutureOption[A](private val fua: Fu[Option[A]]) extends AnyVal {
|
||||
|
||||
def flatten(msg: => String): Fu[A] = fua flatMap {
|
||||
_.fold[Fu[A]](fufail(msg))(fuccess(_))
|
||||
}
|
||||
|
||||
def orElse(other: => Fu[Option[A]]): Fu[Option[A]] = fua flatMap {
|
||||
_.fold(other) { x => fuccess(Some(x)) }
|
||||
}
|
||||
|
||||
def getOrElse(other: => Fu[A]): Fu[A] = fua flatMap { _.fold(other)(fuccess) }
|
||||
}
|
||||
|
||||
final class PimpedFutureValid[A](private val fua: Fu[Valid[A]]) extends AnyVal {
|
||||
|
||||
def flatten: Fu[A] = fua flatMap { _.fold[Fu[A]](fufail(_), fuccess(_)) }
|
||||
}
|
||||
|
||||
final class PimpedTraversableFuture[A, M[X] <: TraversableOnce[X]](private val t: M[Fu[A]]) extends AnyVal {
|
||||
import scala.collection.generic.CanBuildFrom
|
||||
|
||||
def sequenceFu(implicit cbf: CanBuildFrom[M[Fu[A]], A, M[A]]): Fu[M[A]] =
|
||||
Future.sequence(t)
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package lila.base
|
||||
|
||||
import play.api.libs.json._
|
||||
|
||||
final class PimpedJsObject(private val js: JsObject) extends AnyVal {
|
||||
|
||||
def str(key: String): Option[String] =
|
||||
(js \ key).asOpt[String]
|
||||
|
||||
def int(key: String): Option[Int] =
|
||||
(js \ key).asOpt[Int]
|
||||
|
||||
def long(key: String): Option[Long] =
|
||||
(js \ key).asOpt[Long]
|
||||
|
||||
def boolean(key: String): Option[Boolean] =
|
||||
(js \ key).asOpt[Boolean]
|
||||
|
||||
def obj(key: String): Option[JsObject] =
|
||||
(js \ key).asOpt[JsObject]
|
||||
|
||||
def arr(key: String): Option[JsArray] =
|
||||
(js \ key).asOpt[JsArray]
|
||||
|
||||
def arrAs[A](key: String)(as: JsValue => Option[A]): Option[List[A]] =
|
||||
arr(key) map { j =>
|
||||
(j.value.map(as)(scala.collection.breakOut): List[Option[A]]).flatten
|
||||
}
|
||||
|
||||
def ints(key: String): Option[List[Int]] = arrAs(key)(_.asOpt[Int])
|
||||
|
||||
def strs(key: String): Option[List[String]] = arrAs(key)(_.asOpt[String])
|
||||
|
||||
def objs(key: String): Option[List[JsObject]] = arrAs(key)(_.asOpt[JsObject])
|
||||
|
||||
def get[A: Reads](key: String): Option[A] =
|
||||
(js \ key).asOpt[A]
|
||||
|
||||
def noNull = JsObject {
|
||||
js.fields collect {
|
||||
case (key, value) if value != JsNull => key -> value
|
||||
}
|
||||
}
|
||||
|
||||
def add(pair: (String, Boolean)): JsObject =
|
||||
if (pair._2) js + (pair._1 -> JsBoolean(true))
|
||||
else js
|
||||
|
||||
def add[A: Writes](pair: (String, Option[A])): JsObject =
|
||||
pair._2.fold(js) { a => js + (pair._1 -> Json.toJson(a)) }
|
||||
}
|
||||
|
||||
final class PimpedJsValue(private val js: JsValue) extends AnyVal {
|
||||
|
||||
def str(key: String): Option[String] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[String]
|
||||
}
|
||||
|
||||
def int(key: String): Option[Int] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[Int]
|
||||
}
|
||||
|
||||
def long(key: String): Option[Long] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[Long]
|
||||
}
|
||||
|
||||
def boolean(key: String): Option[Boolean] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[Boolean]
|
||||
}
|
||||
|
||||
def obj(key: String): Option[JsObject] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[JsObject]
|
||||
}
|
||||
|
||||
def arr(key: String): Option[JsArray] =
|
||||
js.asOpt[JsObject] flatMap { obj =>
|
||||
(obj \ key).asOpt[JsArray]
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package lila.base
|
||||
|
||||
import java.lang.Math.{ min, max }
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
||||
import LilaTypes._
|
||||
import ornicar.scalalib.Zero
|
||||
|
||||
final class PimpedBoolean(private val self: Boolean) extends AnyVal {
|
||||
/**
|
||||
* Replaces scalaz boolean ops
|
||||
* so ?? works on Zero and not Monoid
|
||||
*/
|
||||
def ??[A](a: => A)(implicit z: Zero[A]): A = if (self) a else z.zero
|
||||
|
||||
def !(f: => Unit) = if (self) f
|
||||
|
||||
def fold[A](t: => A, f: => A): A = if (self) t else f
|
||||
|
||||
def ?[X](t: => X) = new { def |(f: => X) = if (self) t else f }
|
||||
|
||||
def option[A](a: => A): Option[A] = if (self) Some(a) else None
|
||||
|
||||
def optionFu[A](v: => Fu[A])(implicit ec: ExecutionContext): Fu[Option[A]] =
|
||||
if (self) v map { Some(_) } else fuccess(None)
|
||||
}
|
||||
|
||||
final class PimpedLong(private val self: Long) extends AnyVal {
|
||||
|
||||
def atLeast(bottomValue: Long): Long = max(self, bottomValue)
|
||||
|
||||
def atMost(topValue: Long): Long = min(self, topValue)
|
||||
}
|
||||
|
||||
final class PimpedInt(private val self: Int) extends AnyVal {
|
||||
|
||||
def atLeast(bottomValue: Int): Int = max(self, bottomValue)
|
||||
|
||||
def atMost(topValue: Int): Int = min(self, topValue)
|
||||
}
|
||||
|
||||
final class PimpedFloat(private val self: Float) extends AnyVal {
|
||||
|
||||
def atLeast(bottomValue: Float): Float = max(self, bottomValue)
|
||||
|
||||
def atMost(topValue: Float): Float = min(self, topValue)
|
||||
}
|
||||
|
||||
final class PimpedDouble(private val self: Double) extends AnyVal {
|
||||
|
||||
def atLeast(bottomValue: Double): Double = max(self, bottomValue)
|
||||
|
||||
def atMost(topValue: Double): Double = min(self, topValue)
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package lila.base
|
||||
|
||||
import java.util.Base64
|
||||
import scala.util.Try
|
||||
|
||||
final class PimpedTryList[A](private val list: List[Try[A]]) extends AnyVal {
|
||||
def sequence: Try[List[A]] = Try(list map { _.get })
|
||||
}
|
||||
|
||||
final class PimpedList[A](private val list: List[A]) extends AnyVal {
|
||||
def sortLike[B](other: List[B], f: A => B): List[A] = list.sortWith {
|
||||
(x, y) => other.indexOf(f(x)) < other.indexOf(f(y))
|
||||
}
|
||||
}
|
||||
|
||||
final class PimpedSeq[A](private val seq: Seq[A]) extends AnyVal {
|
||||
def has(a: A) = seq contains a
|
||||
}
|
||||
|
||||
final class PimpedByteArray(private val self: Array[Byte]) extends AnyVal {
|
||||
def toBase64 = Base64.getEncoder.encodeToString(self)
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
package lila.base
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.Future
|
||||
import scala.util.Try
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import org.joda.time.DateTime
|
||||
import ornicar.scalalib.Zero
|
||||
import scalaz._
|
||||
import Scalaz._
|
||||
|
||||
import LilaTypes._
|
||||
|
||||
final class PimpedOption[A](private val self: Option[A]) extends AnyVal {
|
||||
|
||||
import scalaz.std.{ option => o }
|
||||
|
||||
def fold[X](some: A => X, none: => X): X = self.fold(none)(some)
|
||||
|
||||
def |(a: => A): A = self getOrElse a
|
||||
|
||||
def unary_~(implicit z: Zero[A]): A = self getOrElse z.zero
|
||||
def orDefault(implicit z: Zero[A]): A = self getOrElse z.zero
|
||||
|
||||
def toSuccess[E](e: => E): scalaz.Validation[E, A] = o.toSuccess(self)(e)
|
||||
|
||||
def toFailure[B](b: => B): scalaz.Validation[A, B] = o.toFailure(self)(b)
|
||||
|
||||
def toTry(err: => Exception): Try[A] =
|
||||
self.fold[Try[A]](scala.util.Failure(err))(scala.util.Success.apply)
|
||||
|
||||
def err(message: => String): A = self.getOrElse(sys.error(message))
|
||||
|
||||
def ifNone(n: => Unit): Unit = if (self.isEmpty) n
|
||||
|
||||
def has(a: A) = self contains a
|
||||
}
|
||||
|
||||
final class PimpedString(private val s: String) extends AnyVal {
|
||||
|
||||
def boot[A](v: => A): A = lila.common.Chronometer.syncEffect(v) { lap =>
|
||||
lila.log.boot.info(s"${lap.millis}ms $s")
|
||||
}
|
||||
}
|
||||
|
||||
final class PimpedConfig(private val config: Config) extends AnyVal {
|
||||
|
||||
def millis(name: String): Int = config.getDuration(name, TimeUnit.MILLISECONDS).toInt
|
||||
def seconds(name: String): Int = config.getDuration(name, TimeUnit.SECONDS).toInt
|
||||
def duration(name: String): FiniteDuration = millis(name).millis
|
||||
}
|
||||
|
||||
final class PimpedDateTime(private val date: DateTime) extends AnyVal {
|
||||
def getSeconds: Long = date.getMillis / 1000
|
||||
def getCentis: Long = date.getMillis / 10
|
||||
}
|
||||
|
||||
final class PimpedValid[A](private val v: Valid[A]) extends AnyVal {
|
||||
|
||||
def future: Fu[A] = v fold (errs => fufail(errs.shows), fuccess)
|
||||
}
|
||||
|
||||
final class PimpedTry[A](private val v: Try[A]) extends AnyVal {
|
||||
|
||||
def fold[B](fe: Exception => B, fa: A => B): B = v match {
|
||||
case scala.util.Failure(e: Exception) => fe(e)
|
||||
case scala.util.Failure(e) => throw e
|
||||
case scala.util.Success(a) => fa(a)
|
||||
}
|
||||
|
||||
def future: Fu[A] = fold(Future.failed, fuccess)
|
||||
}
|
||||
|
||||
final class PimpedEither[A, B](private val v: Either[A, B]) extends AnyVal {
|
||||
import ornicar.scalalib.ValidTypes
|
||||
|
||||
def toValid: Valid[B] = ValidTypes.eitherToValid(v)
|
||||
}
|
||||
|
||||
final class PimpedFiniteDuration(private val d: FiniteDuration) extends AnyVal {
|
||||
|
||||
def toCentis = chess.Centis {
|
||||
// divide by Double, then round, to avoid rounding issues with just `/10`!
|
||||
math.round {
|
||||
if (d.unit eq MILLISECONDS) d.length / 10d
|
||||
else d.toMillis / 10d
|
||||
}
|
||||
}
|
||||
|
||||
def abs = if (d.length < 0) -d else d
|
||||
}
|
|
@ -70,7 +70,7 @@ private final class Indexer(storage: Storage, sequencer: ActorRef) {
|
|||
PovToEntry(game, user.id, provisional = nb < 10).addFailureEffect { e =>
|
||||
println(e)
|
||||
e.printStackTrace
|
||||
} map (_.right.toOption)
|
||||
} map (_.toOption)
|
||||
}
|
||||
val query = gameQuery(user) ++ $doc(Game.BSONFields.createdAt $gte from)
|
||||
GameRepo.sortedCursor(query, Query.sortChronological)
|
||||
|
|
|
@ -23,12 +23,13 @@ object Dependencies {
|
|||
}
|
||||
|
||||
val scalaz = "org.scalaz" %% "scalaz-core" % "7.2.15"
|
||||
val scalalib = "com.github.ornicar" %% "scalalib" % "6.5"
|
||||
val scalalib = "com.github.ornicar" %% "scalalib" % "6.4"
|
||||
val typesafeConfig = "com.typesafe" % "config" % "1.3.1"
|
||||
val findbugs = "com.google.code.findbugs" % "jsr305" % "3.0.1"
|
||||
val hasher = "com.roundeights" %% "hasher" % "1.2.0"
|
||||
val jodaTime = "joda-time" % "joda-time" % "2.9.9"
|
||||
val chess = "org.lichess" %% "scalachess" % "6.19"
|
||||
|
||||
val chess = "org.lichess" %% "scalachess" % "6.18"
|
||||
val maxmind = "com.sanoma.cda" %% "maxmind-geoip2-scala" % "1.2.3-THIB"
|
||||
val prismic = "io.prismic" %% "scala-kit" % "1.2.11-THIB"
|
||||
val java8compat = "org.scala-lang.modules" %% "scala-java8-compat" % "0.8.0"
|
||||
|
|
Loading…
Reference in a new issue