Воспроизведение JSON Reads/Writes с однопараметрическими классами case
Это создает Writes
для класса case
import play.api.libs.json._
import play.api.libs.functional.syntax._
case class A(a: String, b: String, c: String)
(JsPath.write[String] and
JsPath.write[String] and
JsPath.write[String])(unlift(A.unapply))
Это может быть расширено для работы для параметров 2, 3, 4, 5, 6 и т.д.... но не 1.
case class B(a: String)
(JsPath.write[String])(unlift(B.unapply))
Ошибка компилятора:
error: overloaded method value write with alternatives:
(t: String)(implicit w: play.api.libs.json.Writes[String])play.api.libs.json.OWrites[play.api.libs.json.JsValue] <and>
(implicit w: play.api.libs.json.Writes[String])play.api.libs.json.OWrites[String]
cannot be applied to (B => String)
(JsPath.write[String])(unlift(B.unapply))
^
Аналогичная проблема возникает при Reads
.
Как я могу получить Reads
и Writes
для кластеров с одним параметром?
Ответы
Ответ 1
Как сказал Тревис:
- Преобразование существующих Чтений: используйте метод карты
- Преобразование существующих писем: использование contramap
Однако contramap работает только с Writes, которые производят JsObject. Ваши записи не будут выполняться во время выполнения:
val w = JsPath.write[String].contramap[B](_.a)
scala> w.writes(B("Hello"))
java.lang.RuntimeException: when empty JsPath, expecting JsObject
Вы можете создать Writes "с нуля", используя Writes.apply
:
Writes[B](b => JsString(b.a))
Аналогичным образом вы можете создать чтение с помощью Reads.apply.