Написать произвольную ценность, не найденное в классе Case, используя комбинаторы Play's (2.2) Scala JSON
-
21-12-2019 - |
Вопрос
Я хотел бы реализовать генеракодицетагкод, который излучает объект JSON, который не найден в классе, являющийся сериалом.
для класса Case:
case class Foo(i:Int, s:String)
.
Я ищу производить:
{
"i": <int>,
"s": "<string>",
"other": "Some value."
}
.
Наивная первая попытка была:
val writes: Writes[Foo] = ((
(__ \ "i").write[Int] and
(__ \ "s").write[String] and
(__ \ "other").write("Some value.")
)(unlift(Foo.unapply))
.
Естественно, что не скомпированному, поскольку последующие вызовы генеракодицетагкод создают генеракодицетагкод и генеракодиент генеракодичевания и генеракодицетагкод создает генеракодицетагкод. Я бы посмотрел на добавление ценности в результате, создавая генеракодицетагкод, но то, что я нашел выглядит довольно плохо и Управочники языка не будут реализовывать его .
Есть способы работы - вокруг этого, но я бы предпочел не загрязнять свои модели модели с этими значениями декоратора, которые я хотел бы добавить к полученному JSON.
Любые предложения?
Стоит отметить вас CAN идут другое направление, обеспечивая значения с Writes
для случаев, когда значение не существует в JSON, но указано полученным объектом.
Решение
Вы можете сделать это довольно прямолировку, десугарировать немного:
val writes: Writes[Foo] = (
(__ \ "i").write[Int] and
(__ \ "s").write[String] and
(__ \ "other").write[String]
)(foo => (foo.i, foo.s, "Some value."))
.
Генеракодицетагкод - это просто модный способ получить функцию от генеракодицетагкода к кортежу из такого типа, требуемого предыдущей эксплуатационной эффективностью, и вы можете заменить его собственной функцией, которая может добавить все, что вы хотите.
Если вы действительно хотел даже очистить синтаксис, вы могли бы использовать FORMESS :
import shapeless.syntax.std.tuple._
val writes: Writes[Foo] = (
(__ \ "i").write[Int] and
(__ \ "s").write[String] and
(__ \ "other").write[String]
)(_ :+ "Some value.")
.
Это красиво, но может быть излишним.
Другие советы
Другой вариант - использовать объектный построитель, который реализует генеракодицетагкод, который возвращает дополнительные значения.Это делает пишет очистить, но добавляет новый объект.Я обнаружил, что это полезно, хотя, так как как применить, так и непринужденный метод можно использовать для дополнительного массажа данных в конечный объект (например,: https://stackoverflow.com/a/22504468/1085606 )
Пример:
case class Foo(i: Int, s: String)
object FooBuilder {
def unapply(foo: Foo): Option[(Int, String, String)] = {
Some((foo.i, foo.s, "Some extra value"))
}
}
val writes: Writes[Foo] = ((
(__ \ "i").write[Int] and
(__ \ "s").write[String] and
(__ \ "other").write[String]
)(unlift(FooBuilder.unapply))
.