我需要关于Play的Json和Writes特性中优雅的Option处理的建议

le-*_*ude 7 json scala playframework playframework-2.1

我有一个"样式"或"有效scala"类型的问题:我有一个"FeatureCheck"类,我需要在Play框架中序列化为Json.

case class FeatureCheck(val result: Option[Boolean], val missing: Option[Array[String]], val error: Option[String])
Run Code Online (Sandbox Code Playgroud)

我使用自己的"写入"来序列化它,但我的代码看起来很像Java代码.我想序列化check对象中的每个选项只有在它被定义时(最终对象不应该有任何空值).

def writes(check: FeatureCheck): JsValue = {
  val builder = Seq.newBuilder[(String, JsValue)]
  if (check.error.isDefined) {
    builder += "error" -> JsString(check.error.get)
  }
  if (check.missing.isDefined) {
    builder += "missing" -> Json.toJson(check.missing.get)
  }
  if (check.result.isDefined) {
    builder += "result" -> JsBoolean(check.result.get)
  }
  JsObject(builder.result)
}
Run Code Online (Sandbox Code Playgroud)

所以我想知道是否有办法做到这一点,没有那些丑陋的if-then,甚至删除序列的构建器.

感谢您提供的任何帮助或评论.

Clarrifications:

假设我想发送result = true我希望得到的Json是:

{"result":true} 
Run Code Online (Sandbox Code Playgroud)

并不是

{
    "result": true,
    "error": null,
    "missing": []
}
Run Code Online (Sandbox Code Playgroud)

Rég*_*les 5

鉴于您可以简单地将一个选项附加到seq(如果value不为null,请参阅添加到列表),您可以更优雅地执行您想要的操作:

type JsField = (String, JsValue)
def writes(check: FeatureCheck): JsValue = {
  JsObject(
    Seq[JsField]() ++
    check.error.map("error" -> JsString(_)) ++
    check.missing.map("missing" -> Json.toJson(_)) ++
    check.result.map("result" -> JsBoolean(_))    
  )
}
Run Code Online (Sandbox Code Playgroud)