玩 JsPath 为 Infinite Double 写
Play JsPath writes for Infinite Double
我正在尝试实现一个编写 Doubles 的函数,它的值可能为 Infinity(JSON 中不存在)。
以下是我正在努力实现的一些示例:
Input: Double.PositiveInfinity
Output:
{
"positiveInfinty": true,
"negativeInfinty": false,
"value": null
}
Input: 12.3
Output:
{
"positiveInfinty": false,
"negativeInfinty": false,
"value": 12.3
}
到目前为止,我已经创建了一个增强的 JsPath class,并添加了名为 writeInfinite
:
的函数
case class EnhancedJsPath(jsPath: JsPath) {
private def infinityObject(pos: Boolean, neg: Boolean, value: Option[Double]): JsObject = Json.obj(
"positiveInfinity" -> pos,
"negativeInfinity" -> neg,
"value" -> value
)
def writeInfinite: OWrites[Double] = OWrites[Double] { d =>
if (d == Double.PositiveInfinity) { infinityObject(true, false, None) }
else if (d == Double.NegativeInfinity) { infinityObject(false, true, None) }
else { infinityObject(false, false, Some(d)) }
}
}
object EnhancedJsPath {
implicit def jsPathToEnhancedJsPath(jsPath: JsPath): EnhancedJsPath = EnhancedJsPath(jsPath)
}
代码全部编译,这是我正在使用的测试:
case class Dummy(id: String, value: Double)
object Dummy {
implicit val writes: Writes[Dummy] = (
(JsPath \ "id").write[String] and
(JsPath \ "value").writeInfinite
)(unlift(Dummy.unapply))
}
test("EnhancedJsPath.writesInfinite should set positive infinity property") {
val d = Dummy("123", Double.PositiveInfinity, Some(Double.PositiveInfinity))
val result = Json.toJson(d)
val expected = Json.obj(
"id" -> "123",
"value" -> Json.obj(
"positiveInfinity" -> true,
"negativeInfinity" -> false,
"value" -> JsNull
)
)
assert(result == expected)
}
测试失败,因为 result
的值为:
{
"id": "123",
"positiveInfinity": true,
"negativeInfinity": false,
"value": null
}
而不是:
{
"id": "123",
"value": {
"positiveInfinity": true,
"negativeInfinity": false,
"value": null
}
}
我不知道如何修改我的 writeInfinite
以遵守路径。
看看 JsPath#write[A]
或 JsPath#writeNullable[A]
有帮助:
def write[T](implicit w: Writes[T]): OWrites[T] = Writes.at[T](this)(w)
Writes.at
接受 JsPath
,这就是 write
和 writeNullable
保留调用它们的路径的方式。您需要做的就是用它包装您当前的 writeInfinite
实现,同时传递 jsPath
值:
def writeInfinite: OWrites[Double] = Writes.at(jsPath)(OWrites[Double] { d =>
if (d == Double.PositiveInfinity) infinityObject(true, false, None)
else if (d == Double.NegativeInfinity) infinityObject(false, true, None)
else infinityObject(false, false, Some(d))
})
有效:
scala> Json.toJson(d)
res5: play.api.libs.json.JsValue = {"id":"123","value":{"positiveInfinity":true,"negativeInfinity":false,"value":null}}
我正在尝试实现一个编写 Doubles 的函数,它的值可能为 Infinity(JSON 中不存在)。
以下是我正在努力实现的一些示例:
Input: Double.PositiveInfinity
Output:
{
"positiveInfinty": true,
"negativeInfinty": false,
"value": null
}
Input: 12.3
Output:
{
"positiveInfinty": false,
"negativeInfinty": false,
"value": 12.3
}
到目前为止,我已经创建了一个增强的 JsPath class,并添加了名为 writeInfinite
:
case class EnhancedJsPath(jsPath: JsPath) {
private def infinityObject(pos: Boolean, neg: Boolean, value: Option[Double]): JsObject = Json.obj(
"positiveInfinity" -> pos,
"negativeInfinity" -> neg,
"value" -> value
)
def writeInfinite: OWrites[Double] = OWrites[Double] { d =>
if (d == Double.PositiveInfinity) { infinityObject(true, false, None) }
else if (d == Double.NegativeInfinity) { infinityObject(false, true, None) }
else { infinityObject(false, false, Some(d)) }
}
}
object EnhancedJsPath {
implicit def jsPathToEnhancedJsPath(jsPath: JsPath): EnhancedJsPath = EnhancedJsPath(jsPath)
}
代码全部编译,这是我正在使用的测试:
case class Dummy(id: String, value: Double)
object Dummy {
implicit val writes: Writes[Dummy] = (
(JsPath \ "id").write[String] and
(JsPath \ "value").writeInfinite
)(unlift(Dummy.unapply))
}
test("EnhancedJsPath.writesInfinite should set positive infinity property") {
val d = Dummy("123", Double.PositiveInfinity, Some(Double.PositiveInfinity))
val result = Json.toJson(d)
val expected = Json.obj(
"id" -> "123",
"value" -> Json.obj(
"positiveInfinity" -> true,
"negativeInfinity" -> false,
"value" -> JsNull
)
)
assert(result == expected)
}
测试失败,因为 result
的值为:
{
"id": "123",
"positiveInfinity": true,
"negativeInfinity": false,
"value": null
}
而不是:
{
"id": "123",
"value": {
"positiveInfinity": true,
"negativeInfinity": false,
"value": null
}
}
我不知道如何修改我的 writeInfinite
以遵守路径。
看看 JsPath#write[A]
或 JsPath#writeNullable[A]
有帮助:
def write[T](implicit w: Writes[T]): OWrites[T] = Writes.at[T](this)(w)
Writes.at
接受 JsPath
,这就是 write
和 writeNullable
保留调用它们的路径的方式。您需要做的就是用它包装您当前的 writeInfinite
实现,同时传递 jsPath
值:
def writeInfinite: OWrites[Double] = Writes.at(jsPath)(OWrites[Double] { d =>
if (d == Double.PositiveInfinity) infinityObject(true, false, None)
else if (d == Double.NegativeInfinity) infinityObject(false, true, None)
else infinityObject(false, false, Some(d))
})
有效:
scala> Json.toJson(d)
res5: play.api.libs.json.JsValue = {"id":"123","value":{"positiveInfinity":true,"negativeInfinity":false,"value":null}}