Reputation: 2552
I've taken a look to the answers about this topic, but I just haven't got how to fix the problem in this snippet:
object MyObj {
def validate[Z](json: JsValue)(implicit rds: Reads[Z]): Either[Error,Z] = {
json.validate[Z].map{
case r: Z => Right(r) // Type Erasure here....
}.recoverTotal{
e => Left(JsonParsingError(JsError.toFlatJson(e).toString))
}
}
}
Any help?
Upvotes: 1
Views: 1275
Reputation: 36511
I think all you really have to do to kill that error is drop the type ascription : Z
. You already know it will be a Z
if validate
gives you a JsSuccess
in the first place. Otherwise you'll end up in recoverTotal
.
I think you want:
object MyObj {
def validate[Z](json: JsValue)(implicit rds: Reads[Z]): Either[Error,Z] = {
json.validate[Z].map(Right _).recoverTotal{ e =>
Left(JsonParsingError(JsError.toFlatJson(e).toString))
}
}
}
Although what you may really want is:
implicit def readsEither[Z](implicit rds: Reads[Z]): Reads[Either[Error, Z]] = Reads { json =>
rds.reads(json).map(Right(_)).recoverTotal { e =>
JsSuccess(Left(JsonParsingError(JsError.toFlatJson(e).toString)))
}
}
This latter example is nice because it defines a Reads
, which composes nicely.
I haven't tested any of this, and can't really, since I don't have a JsonParsingError
, but this should more or less solve your problem.
Edit: given the fact that your code requires an implicit Reads[Z]
already, you might also try:
def jsonAsEither(json: JsValue)(implicit rds: Reads[Z]) =
Json.fromJson(json).asEither.left.map( /* ... */ ).e
Upvotes: 1