Scala Compiler (2.11.7) Anomaly with JSON Writes

So, I have the following code:

Base:

import play.api.libs.json.{JsNull, Json, JsValue, Writes}
case class Cost(cost: Option[Double])

This compiles:

case object Cost {
  def writes = new Writes[Cost] {
    override def writes(r: Cost): JsValue = {
      val cost = r.cost.map(Json.toJson(_)).getOrElse(JsNull)
      Json.obj(
        "cost" -> cost
      )
    }
  }
}

But it does not compile

case object Cost {
  def writes = new Writes[Cost] {
    override def writes(r: Cost): JsValue = {
      Json.obj(
        "cost" -> r.cost.map(Json.toJson(_)).getOrElse(JsNull)
      )
    }
  }
}

Compiler Error:

type mismatch;
[error]  found   : Object
[error]  required: play.api.libs.json.Json.JsValueWrapper
[error]         "cost" -> r.cost.map(Json.toJson(_)).getOrElse(JsNull)

In the latter case, if I use .asInstanceOf [JsValue], it works, but with IntelliJ it produces this, saying that it is unnecessary, because it cannot be something else that JsValue is anyway. What could be the reason that the Scala compiler (2.11.7) does not detect the class properly?

+4
source share
1 answer

I'm sure the problem comes from .getOrElse(JsNull)

I have successfully compiled this code:

import play.api.libs.json.{JsNull, Json, JsValue, Writes}

case class Cost(cost: Option[Double])

case object Cost {
  def writes = new Writes[Cost] {
    override def writes(r: Cost): JsValue = {
      Json.obj(
        "cost" -> r.cost.map(Json.toJson(_))
      )
    }
  }
}

and analyzed the conclusion:

scala> Cost(Some(5))
res2: Cost = Cost(Some(5.0))

scala> Json.toJson(res2)(Cost.writes)
res5: play.api.libs.json.JsValue = {"cost":5}

Looking for the source of the problem, you can check out a couple of additional solutions, assuming a write function:

val cost = r.cost.map(t => Json.toJson(t))
Json.obj(
  "cost" -> cost
)

Option cost getOrElse, ( ), :

cost.getOrElse[JsValue](JsNull)
cost.getOrElse(JsNull).asInstanceOf[JsValue]

sbt :

[error] (...) type mismatch;
[error]  found   : Object
[error]  required: play.api.libs.json.Json.JsValueWrapper

SBT.

+2

Source: https://habr.com/ru/post/1655617/


All Articles