Reputation: 1030
I'm attempting to interface with the RescueTime API via spray-json. Results are of the form:
{
"notes":"data is an array of arrays (rows), column names for rows in row_headers",
"row_headers":[
"Rank",
"Time Spent (seconds)",
"Number of People",
"Activity",
"Category",
"Productivity"
],
"rows":[
[
1,
16611,
1,
"iTerm",
"Systems Operations",
2
]
]
}
As of yet, I'm attempting to hash out the right case classes. Here's what I've got so far:
package test
import spray.json._
case class RescueTimeApiResult(notes: String, row_headers: List[String], rows: List[List[Either[Int, String]]])
object MyJsonProtocol extends DefaultJsonProtocol {
implicit def rescueTimeApiResultFormat[T: JsonFormat] = jsonFormat3(RescueTimeApiResult)
}
private object Tester extends App {
val notes = "data is an array of arrays (rows), column names for rows in row_headers"
val headers = List("Rank", "Time Spent (seconds)", "Number of People", "Activity", "Category", "Productivity")
val entry1 = List(wrapInt(1),
wrapInt(16611),
wrapInt(1),
wrapString("iTerm"),
wrapString("Systems Operations"),
wrapInt(2))
def wrapInt(x: Int): Either[Int, String] = Left(x)
def wrapString(s: String): Either[Int, String] = Right(s)
val rows = List(entry1)
val obj = RescueTimeApiResult(notes, headers, rows)
println(obj)
import MyJsonProtocol._
println(obj.toJson)
}
This is all well and good, but at compile time scalac
yields:
Error:(31, 15) diverging implicit expansion for type spray.json.JsonWriter[test.RescueTimeApiResult]
starting with method rescueTimeApiResultFormat in object MyJsonProtocol
println(obj.toJson)
^
My understanding of diverging implicit expansion is rough at best. Roughly, there is a cycle in implicit search. As I understand, the toJson
implicit comes from the spray.json._
import which expects a JsonWriter
implicit parameter. This, in turn, is provided by the MyJsonProtocol
object. However, why this particular implicit parameter introduces a cycle is beyond me. One theory is toJson
conversion which applies to Any
might be interfering with the implicit parameter resolution, but that's just a hunch.
Any help is greatly appreciated.
Upvotes: 1
Views: 476
Reputation: 1030
I found a solution, though I'm still very interested in a general explanation.
Essentially, I reduced the problem to the implicit definition of the MyJsonProtocol
. It occurred to me there wasn't much utility in deferring evaluation by declaring the implicit parameter as a def
as opposed to a val
. Furthermore, in removing the type parameter, as my use case is rather concrete, I was able to get around the whole diverging implicit expansion bit.
Upvotes: 1