All Downloads are FREE. Search and download functionalities are using the official Maven repository.

money.rave.common.backend.gson.gson.kt Maven / Gradle / Ivy

package money.rave.common.backend.gson

import com.google.gson.*
import money.rave.common.backend.expression.Expression
import java.lang.reflect.Type
import java.time.ZonedDateTime
import kotlin.reflect.KClass

val commonGson = GsonBuilder()
    .registerTypeAdapterFactory(GsonKotlinAdapterFactory())
    .registerTypeAdapter(ZonedDateTime::class.java, ZonedDateTimeLongTypeAdapter)
    .recursiveExpressionTypeAdapter(Expression::class)
    .create()

private fun GsonBuilder.recursiveExpressionTypeAdapter(kClass: KClass>): GsonBuilder {
    if (kClass.isSealed) {
        ExpressionSerializer.register(kClass.java.simpleName, kClass.java)
        registerTypeAdapter(kClass.java, ExpressionSerializer)

        kClass.sealedSubclasses.forEach {
            recursiveExpressionTypeAdapter(it)
        }
    } else {
        ExpressionSerializer.register(kClass.java.simpleName, kClass.java)
        registerTypeAdapter(kClass.java, ExpressionSerializer)
    }
    return this
}

private object ExpressionSerializer : JsonSerializer>, JsonDeserializer> {

    private val gson = GsonBuilder()
        .registerTypeAdapterFactory(GsonKotlinAdapterFactory())
        .registerTypeAdapter(ZonedDateTime::class.java, ZonedDateTimeLongTypeAdapter)
        .create()

    private val classes: MutableMap>> = mutableMapOf()

    fun register(name: String, clazz: Class>) {
        classes[name] = clazz
    }

    override fun serialize(src: Expression<*>, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
        return JsonObject().apply {
            add(
                src::class.java.simpleName,
                gson.toJsonTree(src),
            )
        }
    }

    override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Expression<*> {
        val name = json.asJsonObject.keySet().first()
        return gson.fromJson(json.asJsonObject.getAsJsonObject(name), classes.getValue(name))
    }
}

fun main() {
    val str = "{\"Literal\":{\"value\":true}}"
    val literal = commonGson.fromJson(str, Expression::class.java)
    println(str)
    println(literal)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy