Skip to content

Instantly share code, notes, and snippets.

@MarkRBM
Created January 2, 2018 21:27
Show Gist options
  • Save MarkRBM/4f9167cd71115857437646560ea03242 to your computer and use it in GitHub Desktop.
Save MarkRBM/4f9167cd71115857437646560ea03242 to your computer and use it in GitHub Desktop.
play json with type parameters
abstract sealed trait Rule[A] {
def roomId: Option[Long] = None
def valid(in: A): Boolean
}
object Rule {
implicit def ruleReads[R, V](implicit rReads: Reads[R], vReads: Reads[V] = null): Reads[Rule[R]] = {
val theVRead = Option(vReads)
val nvr = ???
if (Option(theVRead).isDefined) {
val vr = ???
__.read[ValueRule[R, V]](vr).map(x => x.asInstanceOf[Rule[R]]).orElse(__.read[NoValueRule[R]](nvr).map(x => x.asInstanceOf[Rule[R]]))
} else {
__.read[NoValueRule[R]](nvr).map(x => x.asInstanceOf[Rule[R]])
}
}
implicit def ruleWrites[R, V](implicit rWrites: Writes[R], vWrites: Writes[V] = null): Writes[Rule[R]] = Writes[Rule[R]]{
case nv: NoValueRule[R] => Json.writes[NoValueRule[R]].writes(nv)
case v: ValueRule[R, V] => Json.writes[ValueRule[R, V]].writes(v)
}
}
abstract sealed trait ValueRule[A, B] extends Rule[A] {
def value: B
}
object ValueRule {
implicit def valueRuleReads[R, V](implicit rReads: Reads[R], vReads: Reads[V]): Reads[ValueRule[R, V]] = {
val mlt = Json.reads[MaxLeadTime]
val md = Json.reads[MaxDuration]
__.read[MaxDuration](md).map(x => x.asInstanceOf[ValueRule[R, V]])
.orElse(
__.read[MaxLeadTime](mlt).map(x => x.asInstanceOf[ValueRule[R, V]])
)
}
implicit def valueRuleWrites[R, V](implicit rWrites: Writes[R], vWrites: Writes[V]): Writes[ValueRule[R, V]] = Writes[ValueRule[R, V]]{
case mlt: MaxLeadTime => Json.writes[MaxLeadTime].writes(mlt)
case md: MaxDuration => Json.writes[MaxDuration].writes(md)
}
}
abstract sealed trait NoValueRule[A] extends Rule[A]
object NoValueRule {
implicit def noValueRuleReads[R](implicit rReads: Reads[R]): Reads[NoValueRule[R]] = {
val odwh = Json.reads[OnlyDuringWorkHours]
__.read[OnlyDuringWorkHours](odwh).map(x => x.asInstanceOf[NoValueRule[R]])
}
implicit def noValueRuleWrites[R](implicit rWrites: Writes[R]): Writes[NoValueRule[R]] = Writes[NoValueRule[R]]{
case odwh: OnlyDuringWorkHours => Json.writes[OnlyDuringWorkHours].writes(odwh)
}
}
case class OnlyDuringWorkHours(override val roomId: Option[Long] = None) extends NoValueRule[((ResStart, ResEnd), Center)] {
override def valid(in: ((ResStart, ResEnd), Center)): Boolean = true
}
object OnlyDuringWorkHours {
implicit val format: Format[OnlyDuringWorkHours] = Json.format[OnlyDuringWorkHours]
}
case class MaxLeadTime(override val roomId: Option[Long] = None, override val value: Int) extends ValueRule[ResStart, Int] {
override def valid(in: ResStart): Boolean = true
}
object MaxLeadTime {
implicit val format: Format[MaxLeadTime] = Json.format[MaxLeadTime]
}
case class MaxDuration(override val roomId: Option[Long] = None, override val value: String) extends ValueRule[(ResStart, ResEnd), String] {
override def valid(in: (ResStart, ResEnd)): Boolean = true
}
object MaxDuration {
implicit val format: Format[MaxDuration] = Json.format[MaxDuration]
}
case class Rules(centerId: Long, ruleList: Seq[Rule[_]])
object Rules {
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
implicit val rulesReads: Reads[Rules] = (
(JsPath \ "centerId").read[Long] and
(JsPath \ "ruleList").read[Seq[Rule]]
)(Rules.apply _)
implicit val rulesWrites: Writes[Rules] = (
(JsPath \ "centerId").write[Long] and
???
)(unlift(Rules.unapply))
implicit val format: Format[Rules] = Format(rulesReads, rulesWrites)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment