lila/modules/swiss/src/main/BsonHandlers.scala

139 lines
4.8 KiB
Scala
Raw Normal View History

2020-04-28 19:22:38 -06:00
package lila.swiss
import chess.Color
import chess.format.FEN
import reactivemongo.api.bson._
import scala.concurrent.duration._
2020-04-28 19:22:38 -06:00
import lila.db.BSON
import lila.db.dsl._
import lila.user.User
2020-04-28 19:22:38 -06:00
object BsonHandlers {
2020-04-28 19:22:38 -06:00
implicit val variantHandler = variantByKeyHandler
implicit val clockHandler = clockConfigHandler
2020-05-04 16:59:08 -06:00
implicit val swissPointsHandler = intAnyValHandler[Swiss.Points](_.double, Swiss.Points.apply)
implicit val swissTieBreakHandler = doubleAnyValHandler[Swiss.TieBreak](_.value, Swiss.TieBreak.apply)
implicit val swissPerformanceHandler =
floatAnyValHandler[Swiss.Performance](_.value, Swiss.Performance.apply)
implicit val swissScoreHandler = intAnyValHandler[Swiss.Score](_.value, Swiss.Score.apply)
implicit val roundNumberHandler = intAnyValHandler[SwissRound.Number](_.value, SwissRound.Number.apply)
implicit val swissIdHandler = stringAnyValHandler[Swiss.Id](_.value, Swiss.Id.apply)
implicit val playerIdHandler = stringAnyValHandler[SwissPlayer.Id](_.value, SwissPlayer.Id.apply)
2020-04-28 19:22:38 -06:00
implicit val playerHandler = new BSON[SwissPlayer] {
2020-05-03 19:48:23 -06:00
import SwissPlayer.Fields._
2020-05-05 22:11:15 -06:00
def reads(r: BSON.Reader) =
SwissPlayer(
id = r.get[SwissPlayer.Id](id),
swissId = r.get[Swiss.Id](swissId),
userId = r str userId,
rating = r int rating,
provisional = r boolD provisional,
points = r.get[Swiss.Points](points),
tieBreak = r.get[Swiss.TieBreak](tieBreak),
performance = r.getO[Swiss.Performance](performance),
score = r.get[Swiss.Score](score),
2020-05-06 20:41:28 -06:00
absent = r.boolD(absent),
byes = ~r.getO[Set[SwissRound.Number]](byes)
2020-05-05 22:11:15 -06:00
)
def writes(w: BSON.Writer, o: SwissPlayer) =
$doc(
id -> o.id,
swissId -> o.swissId,
userId -> o.userId,
rating -> o.rating,
provisional -> w.boolO(o.provisional),
points -> o.points,
tieBreak -> o.tieBreak,
performance -> o.performance,
score -> o.score,
2020-05-06 20:41:28 -06:00
absent -> w.boolO(o.absent),
byes -> o.byes.some.filter(_.nonEmpty)
2020-05-05 22:11:15 -06:00
)
2020-04-28 19:22:38 -06:00
}
2020-05-03 09:00:47 -06:00
implicit val pairingStatusHandler = lila.db.dsl.quickHandler[SwissPairing.Status](
{
case BSONBoolean(true) => Left(SwissPairing.Ongoing)
2020-09-21 03:31:16 -06:00
case BSONInteger(index) => Right(Color.fromWhite(index == 0).some)
case _ => Right(none)
2020-05-05 22:11:15 -06:00
},
{
2020-05-03 09:00:47 -06:00
case Left(_) => BSONBoolean(true)
case Right(Some(c)) => BSONInteger(c.fold(0, 1))
2020-05-03 09:00:47 -06:00
case _ => BSONNull
}
)
2020-04-28 19:22:38 -06:00
implicit val pairingHandler = new BSON[SwissPairing] {
2020-05-03 19:48:23 -06:00
import SwissPairing.Fields._
2020-04-29 15:14:35 -06:00
def reads(r: BSON.Reader) =
r.get[List[User.ID]](players) match {
2020-05-03 19:48:23 -06:00
case List(w, b) =>
2020-04-29 15:14:35 -06:00
SwissPairing(
2020-05-04 15:16:36 -06:00
id = r str id,
2020-05-03 19:48:23 -06:00
swissId = r.get[Swiss.Id](swissId),
round = r.get[SwissRound.Number](round),
white = w,
black = b,
status = r.getO[SwissPairing.Status](status) | Right(none),
isForfeit = r.boolD(isForfeit)
2020-04-29 15:14:35 -06:00
)
case _ => sys error "Invalid swiss pairing users"
}
2020-05-05 22:11:15 -06:00
def writes(w: BSON.Writer, o: SwissPairing) =
$doc(
id -> o.id,
swissId -> o.swissId,
round -> o.round,
players -> o.players,
status -> o.status,
isForfeit -> w.boolO(o.isForfeit)
2020-05-05 22:11:15 -06:00
)
2020-04-28 19:22:38 -06:00
}
2020-10-05 06:39:25 -06:00
import SwissCondition.BSONHandlers.AllBSONHandler
2020-05-05 19:26:39 -06:00
implicit val settingsHandler = new BSON[Swiss.Settings] {
2020-05-05 22:11:15 -06:00
def reads(r: BSON.Reader) =
Swiss.Settings(
nbRounds = r.get[Int]("n"),
rated = r.boolO("r") | true,
description = r.strO("d"),
position = r.getO[FEN]("f"),
2020-05-23 21:18:43 -06:00
chatFor = r.intO("c") | Swiss.ChatFor.default,
2020-07-17 07:13:26 -06:00
roundInterval = (r.intO("i") | 60).seconds,
2020-10-05 06:39:25 -06:00
password = r.strO("p"),
conditions = r.getO[SwissCondition.All]("o") getOrElse SwissCondition.All.empty,
forbiddenPairings = r.getD[String]("fp")
2020-05-05 22:11:15 -06:00
)
def writes(w: BSON.Writer, s: Swiss.Settings) =
$doc(
2021-02-17 05:35:55 -07:00
"n" -> s.nbRounds,
"r" -> (!s.rated).option(false),
"d" -> s.description,
"f" -> s.position,
"c" -> (s.chatFor != Swiss.ChatFor.default).option(s.chatFor),
"i" -> s.roundInterval.toSeconds.toInt,
"p" -> s.password,
"o" -> s.conditions.ifNonEmpty,
"fp" -> s.forbiddenPairings.some.filter(_.nonEmpty)
2020-05-05 22:11:15 -06:00
)
2020-05-05 19:26:39 -06:00
}
implicit val swissHandler = Macros.handler[Swiss]
2020-05-15 13:36:11 -06:00
2021-03-02 09:37:44 -07:00
// "featurable" mostly means that the tournament isn't over yet
2020-05-23 11:17:42 -06:00
def addFeaturable(s: Swiss) =
swissHandler.writeTry(s).get ++ {
s.isNotFinished ?? $doc(
"featurable" -> true,
"garbage" -> s.unrealisticSettings.option(true)
)
2020-05-23 11:17:42 -06:00
}
import Swiss.IdName
implicit val SwissIdNameBSONHandler = Macros.handler[IdName]
2020-04-28 19:22:38 -06:00
}