package com.smallhacker.disbrowser.util import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.* import com.fasterxml.jackson.databind.module.SimpleModule typealias KSerializer = T.(gen: JsonGenerator, serializers: SerializerProvider) -> Unit typealias KDeserializer = JsonParser.(ctxt: DeserializationContext) -> T typealias KKeyDeserializer = String.(ctxt: DeserializationContext) -> T interface JsonTypeMapper { val type: Class fun serialize(value: T, gen: JsonGenerator, serializers: SerializerProvider) fun deserialize(p: JsonParser, ctxt: DeserializationContext): T fun keyDeserialize(value: String, ctxt: DeserializationContext): T } inline fun jsonTypeMapper( noinline serializer: KSerializer, noinline deserializer: KDeserializer, noinline keyDeserializer: KKeyDeserializer ) = object : JsonTypeMapper { override val type: Class = T::class.java override fun serialize(value: T, gen: JsonGenerator, serializers: SerializerProvider) = serializer(value, gen, serializers) override fun deserialize(p: JsonParser, ctxt: DeserializationContext) = deserializer(p, ctxt) override fun keyDeserialize(value: String, ctxt: DeserializationContext) = keyDeserializer(value, ctxt) } inline fun ObjectMapper.addMapper( noinline serializer: KSerializer, noinline deserializer: KDeserializer, noinline keyDeserializer: KKeyDeserializer ) = addMapper(jsonTypeMapper(serializer, deserializer, keyDeserializer)) fun ObjectMapper.addMapper(mapper: JsonTypeMapper) = registerModule(object : SimpleModule() { init { val serializer = object : JsonSerializer() { override fun serialize(value: T, gen: JsonGenerator, serializers: SerializerProvider) = mapper.serialize(value, gen, serializers) } val deserializer = object : JsonDeserializer() { override fun deserialize(p: JsonParser, ctxt: DeserializationContext) = mapper.deserialize(p, ctxt) } val keyDeserializer = object : KeyDeserializer() { override fun deserializeKey(key: String, ctxt: DeserializationContext) = mapper.keyDeserialize(key, ctxt) } addSerializer(mapper.type, serializer) addDeserializer(mapper.type, deserializer) addKeySerializer(mapper.type, serializer) addKeyDeserializer(mapper.type, keyDeserializer) } })!!