Advertisement
Pihanya

AnySerializer.kt — kotlinx.serializaiton for Map<String, Any>

Sep 7th, 2023
1,348
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.62 KB | None | 0 0
  1. import kotlinx.serialization.KSerializer
  2. import kotlinx.serialization.Serializer
  3. import kotlinx.serialization.builtins.ListSerializer
  4. import kotlinx.serialization.builtins.MapSerializer
  5. import kotlinx.serialization.builtins.serializer
  6. import kotlinx.serialization.descriptors.SerialDescriptor
  7. import kotlinx.serialization.descriptors.buildClassSerialDescriptor
  8. import kotlinx.serialization.descriptors.element
  9. import kotlinx.serialization.encoding.Decoder
  10. import kotlinx.serialization.encoding.Encoder
  11. import kotlinx.serialization.json.Json
  12. import kotlinx.serialization.json.JsonArray
  13. import kotlinx.serialization.json.JsonDecoder
  14. import kotlinx.serialization.json.JsonElement
  15. import kotlinx.serialization.json.JsonObject
  16. import kotlinx.serialization.json.JsonPrimitive
  17. import kotlinx.serialization.json.boolean
  18. import kotlinx.serialization.json.booleanOrNull
  19. import kotlinx.serialization.json.double
  20. import kotlinx.serialization.json.doubleOrNull
  21. import kotlinx.serialization.json.int
  22. import kotlinx.serialization.json.intOrNull
  23.  
  24. @Serializer(forClass = Any::class)
  25. object AnySerializer : KSerializer<Any> {
  26.  
  27.     override val descriptor: SerialDescriptor =
  28.         buildClassSerialDescriptor("Any") {
  29.             element<String>("String")
  30.             element<Int>("Int")
  31.             element<Double>("Double")
  32.             element<Boolean>("Boolean")
  33.             element<JsonElement>("JsonElement")
  34.         }
  35.  
  36.     override fun serialize(encoder: Encoder, value: Any) {
  37.         when (value) {
  38.             is String -> encoder.encodeString(value)
  39.             is Int -> encoder.encodeInt(value)
  40.             is Double -> encoder.encodeDouble(value)
  41.             is Boolean -> encoder.encodeBoolean(value)
  42.             is JsonElement -> encoder.encodeSerializableValue(JsonElement.serializer(), value)
  43.             is Map<*, *> -> {
  44.                 val mapSerializer = MapSerializer(String.serializer(), AnySerializer)
  45.                 encoder.encodeSerializableValue(mapSerializer, uncheckedCast(value))
  46.             }
  47.             is List<*> -> {
  48.                 val listSerializer = ListSerializer(AnySerializer)
  49.                 encoder.encodeSerializableValue(listSerializer, uncheckedCast(value))
  50.             }
  51.             else -> throw IllegalArgumentException("Unsupported type for AnySerializer: ${value::class}")
  52.         }
  53.     }
  54.  
  55.     override fun deserialize(decoder: Decoder): Any {
  56.         val json = (decoder as? JsonDecoder)?.json ?: Json
  57.         val element = decoder.decodeSerializableValue(JsonElement.serializer())
  58.  
  59.         return when (element) {
  60.             is JsonObject -> element.map { (key, value) ->
  61.                 val mapSerializer = MapSerializer(String.serializer(), AnySerializer)
  62.                 json.decodeFromJsonElement(mapSerializer, element)
  63.             }
  64.  
  65.             is JsonArray -> {
  66.                 val listSerializer = ListSerializer(AnySerializer)
  67.                 json.decodeFromJsonElement(listSerializer, element)
  68.             }
  69.  
  70.             is JsonPrimitive -> {
  71.                 when {
  72.                     element.isString -> element.content
  73.                     element.intOrNull != null -> element.int
  74.                     element.doubleOrNull != null -> element.double
  75.                     element.booleanOrNull != null -> element.boolean
  76.                     else -> throw IllegalArgumentException("Unsupported JSON value for AnySerializer: $element")
  77.                 }
  78.             }
  79.  
  80.             else -> throw IllegalArgumentException("Unsupported JSON value for AnySerializer: $element")
  81.         }
  82.     }
  83. }
  84.  
  85. @Suppress("UNCHECKED_CAST")
  86. fun <T> uncheckedCast(value: Any?): T = (value as T)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement