128 lines
3.9 KiB
Kotlin
128 lines
3.9 KiB
Kotlin
package ru.dbotthepony.kstarbound.json
|
|
|
|
import com.google.common.collect.ImmutableList
|
|
import com.google.common.collect.ImmutableMap
|
|
import com.google.common.collect.ImmutableSet
|
|
import com.google.gson.Gson
|
|
import com.google.gson.JsonArray
|
|
import com.google.gson.JsonElement
|
|
import com.google.gson.JsonNull
|
|
import com.google.gson.JsonObject
|
|
import com.google.gson.TypeAdapter
|
|
import com.google.gson.reflect.TypeToken
|
|
import com.google.gson.stream.JsonReader
|
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
|
import ru.dbotthepony.kommons.gson.set
|
|
import ru.dbotthepony.kstarbound.Starbound
|
|
import ru.dbotthepony.kstarbound.fromJson
|
|
|
|
inline fun <reified T> Gson.getAdapter(): TypeAdapter<T> {
|
|
return getAdapter(object : TypeToken<T>() {})
|
|
}
|
|
|
|
inline fun <reified C : Collection<E>, reified E> Gson.collectionAdapter(): TypeAdapter<C> {
|
|
return getAdapter(TypeToken.getParameterized(C::class.java, E::class.java)) as TypeAdapter<C>
|
|
}
|
|
|
|
inline fun <reified K, reified V> Gson.mapAdapter(): TypeAdapter<ImmutableMap<K, V>> {
|
|
return getAdapter(TypeToken.getParameterized(ImmutableMap::class.java, K::class.java, V::class.java)) as TypeAdapter<ImmutableMap<K, V>>
|
|
}
|
|
|
|
inline fun <reified E> Gson.listAdapter(): TypeAdapter<ImmutableList<E>> {
|
|
return collectionAdapter()
|
|
}
|
|
|
|
inline fun <reified A, reified B> Gson.pairAdapter(): TypeAdapter<Pair<A, B>> {
|
|
return getAdapter(TypeToken.getParameterized(Pair::class.java, A::class.java, B::class.java)) as TypeAdapter<Pair<A, B>>
|
|
}
|
|
|
|
inline fun <reified A, reified B> Gson.pairListAdapter(): TypeAdapter<ImmutableList<Pair<A, B>>> {
|
|
return getAdapter(TypeToken.getParameterized(ImmutableList::class.java, TypeToken.getParameterized(Pair::class.java, A::class.java, B::class.java).type)) as TypeAdapter<ImmutableList<Pair<A, B>>>
|
|
}
|
|
|
|
inline fun <reified E> Gson.mutableListAdapter(): TypeAdapter<ArrayList<E>> {
|
|
return collectionAdapter()
|
|
}
|
|
|
|
inline fun <reified E> Gson.setAdapter(): TypeAdapter<ImmutableSet<E>> {
|
|
return collectionAdapter()
|
|
}
|
|
|
|
inline fun <reified A, reified B> Gson.pairSetAdapter(): TypeAdapter<ImmutableSet<Pair<A, B>>> {
|
|
return getAdapter(TypeToken.getParameterized(ImmutableSet::class.java, TypeToken.getParameterized(Pair::class.java, A::class.java, B::class.java).type)) as TypeAdapter<ImmutableSet<Pair<A, B>>>
|
|
}
|
|
|
|
inline fun <reified E> Gson.mutableSetAdapter(): TypeAdapter<ObjectOpenHashSet<E>> {
|
|
return collectionAdapter()
|
|
}
|
|
|
|
/**
|
|
* It is implied that [base] is a copy that can be modified
|
|
*/
|
|
fun mergeJson(base: JsonElement, with: JsonElement): JsonElement {
|
|
if (base is JsonObject && with is JsonObject) {
|
|
for ((k, v) in with.entrySet()) {
|
|
base[k] = mergeJson(base[k] ?: JsonNull.INSTANCE, v)
|
|
}
|
|
|
|
return base
|
|
} else if (with.isJsonNull) {
|
|
return base
|
|
} else {
|
|
return with.deepCopy()
|
|
}
|
|
}
|
|
|
|
fun mergeJson(base: JsonElement, with: Map<String, JsonElement>): JsonElement {
|
|
if (base is JsonObject) {
|
|
for ((k, v) in with) {
|
|
base[k] = mergeJson(base[k] ?: JsonNull.INSTANCE, v)
|
|
}
|
|
|
|
return base
|
|
} else {
|
|
return JsonObject().apply {
|
|
for ((k, v) in with) {
|
|
add(k, v.deepCopy())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun mergeJson(base: JsonElement, with: JsonElement, vararg rest: JsonElement): JsonElement {
|
|
var base = mergeJson(base, with)
|
|
|
|
for (v in rest) {
|
|
base = mergeJson(base, v)
|
|
}
|
|
|
|
return base
|
|
}
|
|
|
|
fun mergeJson(base: JsonObject, with: JsonElement): JsonObject {
|
|
check(mergeJson(base as JsonElement, with) === base)
|
|
return base
|
|
}
|
|
|
|
fun mergeJson(base: JsonObject, with: JsonElement, vararg rest: JsonElement): JsonObject {
|
|
check(mergeJson(base as JsonElement, with) === base)
|
|
|
|
for (v in rest) {
|
|
check(mergeJson(base as JsonElement, v) === base)
|
|
}
|
|
|
|
return base
|
|
}
|
|
|
|
fun jsonArrayOf(vararg elements: JsonElement): JsonArray {
|
|
val array = JsonArray(elements.size)
|
|
elements.forEach { array.add(it) }
|
|
return array
|
|
}
|
|
|
|
fun jsonArrayOf(vararg elements: Any?): JsonArray {
|
|
val array = JsonArray(elements.size)
|
|
elements.forEach { array.add(Starbound.gson.toJsonTree(it)) }
|
|
return array
|
|
}
|