KOptional type adapter

This commit is contained in:
DBotThePony 2024-02-03 19:55:47 +07:00
parent 5c1a5b4d43
commit af4b3dd726
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 58 additions and 5 deletions

View File

@ -4,7 +4,7 @@ kotlin.code.style=official
specifyKotlinAsDependency=false
projectGroup=ru.dbotthepony.kommons
projectVersion=1.6.0
projectVersion=1.7.0
guavaDepVersion=33.0.0
gsonDepVersion=2.8.9

View File

@ -0,0 +1,53 @@
package ru.dbotthepony.kommons.gson
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
import ru.dbotthepony.kommons.core.KOptional
import java.lang.reflect.ParameterizedType
@Suppress("DEPRECATION")
object KOptionalTypeAdapter : TypeAdapterFactory {
override fun <T : Any> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
if (type.rawType === KOptional.Nullable::class.java || type.rawType === KOptional::class.java || type.rawType === KOptional.NotNull::class.java) {
val notnull = type.rawType === KOptional.NotNull::class.java
val param = (type.type as? ParameterizedType ?: return null).actualTypeArguments[0]
val token = TypeToken.get(param)
val isBool = token.rawType === Boolean::class.java
return object : TypeAdapter<KOptional<Any?>>() {
private val adapter0 = gson.getAdapter(token) as TypeAdapter<Any?>
override fun write(out: JsonWriter, value: KOptional<Any?>?) {
if (value === null) {
out.nullValue()
} else if (value.isPresent) {
adapter0.write(out, value.value)
}
}
override fun read(`in`: JsonReader): KOptional<Any?> {
if (isBool) {
if (notnull) {
return KOptional((adapter0.read(`in`) ?: throw JsonSyntaxException("This KOptional does not accept nulls")) as Boolean) as KOptional<Any?>
} else {
return KOptional(adapter0.read(`in`) as Boolean?) as KOptional<Any?>
}
} else {
if (notnull) {
return KOptional(adapter0.read(`in`) ?: throw JsonSyntaxException("This KOptional does not accept nulls"))
} else {
return KOptional(adapter0.read(`in`))
}
}
}
} as TypeAdapter<T>
} else {
return null
}
}
}

View File

@ -95,10 +95,10 @@ class KOptional<T> private constructor(private val _value: T, val isPresent: Boo
}
// gson hack since type token can't diff between nullable and non-null types
@Deprecated("internal class")
internal class Nullable<T : Any?> private constructor()
@Deprecated("internal class")
internal class NotNull<T : Any> private constructor()
@Deprecated("reflection class, don't use directly")
class Nullable<T : Any?> private constructor()
@Deprecated("reflection class, don't use directly")
class NotNull<T : Any> private constructor()
companion object {
private val EMPTY = KOptional(null, false)