Я думаю, что все, что вам действительно нужно сделать, чтобы убить эту ошибку, отбрасывает тип подписи : Z
. Вы уже знаете, что это будет Z
, если validate
дает вам JsSuccess
. В противном случае вы окажетесь в recoverTotal
.
Я думаю, что вы хотите:
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))
}
}
}
Хотя то, что вы можете действительно хотите:
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)))
}
}
Этот последний пример хорош, поскольку он определяет Reads
, который сочиняет красиво.
Я не тестировал это, и не могу, потому что у меня нет JsonParsingError
, но это должно более или менее решить вашу проблему.
Edit: учитывая тот факт, что ваш код требует неявного Reads[Z]
уже, вы можете также попробовать:
def jsonAsEither(json: JsValue)(implicit rds: Reads[Z]) =
Json.fromJson(json).asEither.left.map(/* ... */).e
Просто прочитайте уведомление для редактирования вы предложили - я предлагаю оставить его как 'Считывает '. Вы можете применить его к 'JsValue', выполнив' readsEither.reads (json) 'или' Json.fromJson', а затем вы можете безопасно использовать '.get' в результирующем значении для распаковки получаемого' JsSuccess', потому что вы знаете, что 'readsEither' уже восстанавливает все возможные сбои. Это немного более многословный, но он более идиоматичен и сложен таким образом. Я также добавил еще один, возможно, более сжатый способ перейти непосредственно к «Либо», если вы не хотите идти по маршруту «Читает». – acjay