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 应该替换成什么键?