JsonIter Scala - 格式宏
JsonIter Scala - Format macro
在 Play Json 中,您可以使用此宏 Jsonx.formatInline
,例如,它将 json 对象内联到它的 json 属性。有什么方法可以使用 jsoniter 库来实现吗?
例如,在这段代码中:
case class Foo(values : String)
case class WrapperOfFoo(val : rapperOfFoo)
val codec : JsonValueCodec[[WrapperOfFoo]] = JsonCodecMaker.make
val messageFoo = new Foo("test")
val message = new WrapperOfFoo(messageFoo)
val json = writeToArray(message)(codec).map(_.toChar).mkString
println(json)
结果是:
{
"val": {
"values": "test"
}
}
期望的输出:
{
"val" : "test"
}
因为它只是一个只有一个 属性 的包装器,我希望它被内联,有没有办法在 JsonIter 中实现这个?
作为对我的评论(关于隐式 class)的补充,这就是我的意思:
implicit class CodecOps[A](codec: JsonValueCodec[A]) {
def encodeBy[B](mapFunc: A => B)(implicit bCodec: JsonValueCodec[B]): JsonValueCodec[A] =
new JsonValueCodec[A] {
override def decodeValue(in: JsonReader, default: A): A = codec.decodeValue(in, default)
override def encodeValue(x: A, out: JsonWriter): Unit =
bCodec.encodeValue(mapFunc(x), out)
override def nullValue: A = codec.nullValue
}
def decodedBy[B](contraMapFunc: B => A)(implicit bCodec: JsonValueCodec[B]): JsonValueCodec[A] =
new JsonValueCodec[A] {
override def decodeValue(in: JsonReader, default: A): A =
contraMapFunc(bCodec.decodeValue(in, bCodec.nullValue))
override def encodeValue(x: A, out: JsonWriter): Unit = codec.encodeValue(x, out)
override def nullValue: A = codec.nullValue
}
}
// And then inside your models, assuming implicit JsonValueCodec[Foo] is defined earlier
implicit val codec : JsonValueCodec[FooWrapper] = JsonCodecMaker.make[FooWrapper]
.encodeBy(_.foo)
.decodedBy(FooWrapper.apply)
println(json)
// result => {"values":"test"}
println(readFromString[FooWrapper]("{\"values\":\"test\"}"))
// result => FooWrapper(Foo(test))
请注意,这与 Jsonx.formatInline
中的行为相同,因此它不会 return {"value": "test"}
。想象一下,如果 Foo
是一个复杂的结构会怎样? value
应该替换成什么键?
在 Play Json 中,您可以使用此宏 Jsonx.formatInline
,例如,它将 json 对象内联到它的 json 属性。有什么方法可以使用 jsoniter 库来实现吗?
例如,在这段代码中:
case class Foo(values : String)
case class WrapperOfFoo(val : rapperOfFoo)
val codec : JsonValueCodec[[WrapperOfFoo]] = JsonCodecMaker.make
val messageFoo = new Foo("test")
val message = new WrapperOfFoo(messageFoo)
val json = writeToArray(message)(codec).map(_.toChar).mkString
println(json)
结果是:
{
"val": {
"values": "test"
}
}
期望的输出:
{
"val" : "test"
}
因为它只是一个只有一个 属性 的包装器,我希望它被内联,有没有办法在 JsonIter 中实现这个?
作为对我的评论(关于隐式 class)的补充,这就是我的意思:
implicit class CodecOps[A](codec: JsonValueCodec[A]) {
def encodeBy[B](mapFunc: A => B)(implicit bCodec: JsonValueCodec[B]): JsonValueCodec[A] =
new JsonValueCodec[A] {
override def decodeValue(in: JsonReader, default: A): A = codec.decodeValue(in, default)
override def encodeValue(x: A, out: JsonWriter): Unit =
bCodec.encodeValue(mapFunc(x), out)
override def nullValue: A = codec.nullValue
}
def decodedBy[B](contraMapFunc: B => A)(implicit bCodec: JsonValueCodec[B]): JsonValueCodec[A] =
new JsonValueCodec[A] {
override def decodeValue(in: JsonReader, default: A): A =
contraMapFunc(bCodec.decodeValue(in, bCodec.nullValue))
override def encodeValue(x: A, out: JsonWriter): Unit = codec.encodeValue(x, out)
override def nullValue: A = codec.nullValue
}
}
// And then inside your models, assuming implicit JsonValueCodec[Foo] is defined earlier
implicit val codec : JsonValueCodec[FooWrapper] = JsonCodecMaker.make[FooWrapper]
.encodeBy(_.foo)
.decodedBy(FooWrapper.apply)
println(json)
// result => {"values":"test"}
println(readFromString[FooWrapper]("{\"values\":\"test\"}"))
// result => FooWrapper(Foo(test))
请注意,这与 Jsonx.formatInline
中的行为相同,因此它不会 return {"value": "test"}
。想象一下,如果 Foo
是一个复杂的结构会怎样? value
应该替换成什么键?