我正在尝试为基本上看起来像这样的 AST 创建 play-json 读写
abstract sealed trait Rule[A] {
def roomId: Option[Long] = None
def valid(in: A): Boolean
}
abstract sealed trait ValueRule[A, B] extends Rule[A] {
def value: B
}
abstract sealed trait NoValueRule[A] extends Rule[A]
case class OnlyDuringWorkHours(override val roomId: Option[Long] = None) extends NoValueRule[((ResStart, ResEnd), Center)] {
override def valid(in: ((ResStart, ResEnd), Center)): Boolean = true
}
case class MaxLeadTime(override val roomId: Option[Long] = None, override val value: Int) extends ValueRule[ResStart, Int] {
override def valid(in: ResStart): Boolean = true
}
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
}
case class Rules(centerId: Long, ruleList: Seq[Rule[_]])
我这样做的尝试看起来像这样
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)
}
}
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)
}
}
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)
}
}
object OnlyDuringWorkHours {
implicit val format: Format[OnlyDuringWorkHours] = Json.format[OnlyDuringWorkHours]
}
object MaxLeadTime {
implicit val format: Format[MaxLeadTime] = Json.format[MaxLeadTime]
}
object MaxDuration {
implicit val format: Format[MaxDuration] = Json.format[MaxDuration]
}
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)
}
这给我留下了两个问题。
首先是,如果我在 Rule.ruleReads 的两个实例中插入我认为正确的表达式???
,Json.reads[NoValueRule[R]]
并且Json.reads[ValueRule[R, V]]
分别得到以下编译错误
cmd16.sc:8: type mismatch;
found : play.api.libs.json.JsResult[Helper.this.OnlyDuringWorkHours]
required: play.api.libs.json.JsResult[Helper.this.NoValueRule[R]]
val nvr = Json.reads[NoValueRule[R]]
^cmd16.sc:11: type mismatch;
found : play.api.libs.json.JsResult[Helper.this.MaxLeadTime]
required: play.api.libs.json.JsResult[Helper.this.ValueRule[R,V]]
val vr = Json.reads[ValueRule[R, V]]
^
第二个是如果我离开,???
以便该部分编译它然后无法编译规则对象
cmd17.sc:71: No Json deserializer found for type Seq[cmd17Wrapper.this.cmd16.wrapper.Rule]. Try to implement an implicit Reads or Format for this type.
(JsPath \ "ruleList").read[Seq[Rule]]
^
我可以改为让规则读/写格式并得到一个非常相似的错误
我认为 2 的问题是包含 a 的规则与我定义的隐式读取之间的区别Seq[Rule[_]]
应该涵盖任何特定规则但不是可以是任何规则的规则
有什么想法可以让这个工作吗?我觉得这应该是可能的,但也许不是。