https://kotlinlang.org logo
#serialization
Title
# serialization
a

adev_one

12/06/2018, 7:36 AM
Is there way to deserialize
JsonElemet
as field of
@Serializable
class? Example:
Copy code
@Serializable
data class Test(
    val a: Int,
    val b: JsonElement
)

val test = JSON.parse(Test.serializer(), """{"a":1,"b":{"test":"test2"}}""")
println(test.toString())
s

sandwwraith

12/06/2018, 10:05 AM
This functionality was recently added but has not been released yet 😞
a

adev_one

12/06/2018, 1:08 PM
So, I’ll wait for the release. Thank you for information! I found temporary solution (not for production)
Copy code
@Serializer(forClass = JsonElement::class)
object JsonElementSerializer : KSerializer<JsonElement> {
    override val descriptor: SerialDescriptor = StringDescriptor

    private val jsonInputW = JSON.JsonOutput::class.declaredMemberProperties
        .find { it.name == "w" }!!
        .also { it.isAccessible = true }
    private val jsonLiteralBody = JsonLiteral::class.declaredMemberProperties
        .find { it.name == "body" }!!
        .also { it.isAccessible = true }
    private var print: KFunction<*>? = null
    override fun serialize(output: Encoder, obj: JsonElement) {
        if (obj is JsonLiteral && jsonLiteralBody.get(obj) is String) {
            output.encodeString(obj.toString())
        } else {
            val composer = jsonInputW.get(output as JSON.JsonOutput)!!
            if (print == null) {
                print = composer::class.functions
                    .find { it.name == "print" && it.valueParameters.firstOrNull()?.type?.toString() == "kotlin.String" }!!
                    .also { it.isAccessible = true }
            }
            print!!.call(composer, obj.toString())
        }
    }

    private val jsonInputP = JSON.JsonInput::class.declaredMemberProperties
        .find { it.name == "p" }!!.also { it.isAccessible = true }
    private val jsonTreeParserConstructor = JsonTreeParser::class.constructors
        .find { it.parameters.first().name == "p" }!!
    override fun deserialize(input: Decoder) = run {
        val parser = jsonInputP.get(input as JSON.JsonInput)
        jsonTreeParserConstructor.call(parser).read()
    }
}
6 Views