Created
January 2, 2018 21:27
-
-
Save MarkRBM/4f9167cd71115857437646560ea03242 to your computer and use it in GitHub Desktop.
play json with type parameters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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