1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-20 01:29:09 -05:00

Fix string pair list type converter (#970)

This commit is contained in:
Mikołaj Pich 2020-09-29 11:42:54 +02:00 committed by GitHub
parent d020b01794
commit e5661098d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 100 additions and 6 deletions

View File

@ -127,7 +127,7 @@ configurations.all {
} }
dependencies { dependencies {
implementation "io.github.wulkanowy:sdk:0.21.0" implementation "io.github.wulkanowy:sdk:84c0703"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.data.db
import androidx.room.TypeConverter import androidx.room.TypeConverter
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.Types import com.squareup.moshi.Types
import io.github.wulkanowy.data.db.adapters.PairAdapterFactory
import java.time.Instant import java.time.Instant
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
@ -12,14 +13,14 @@ import java.util.Date
class Converters { class Converters {
private val moshi by lazy { Moshi.Builder().build() } private val moshi by lazy { Moshi.Builder().add(PairAdapterFactory).build() }
private val integerListAdapter by lazy { private val integerListAdapter by lazy {
moshi.adapter<List<Int>>(Types.newParameterizedType(List::class.java, Integer::class.java)) moshi.adapter<List<Int>>(Types.newParameterizedType(List::class.java, Integer::class.java))
} }
private val stringMapAdapter by lazy { private val stringListPairAdapter by lazy {
moshi.adapter<Map<String, String>>(Types.newParameterizedType(MutableMap::class.java, String::class.java, String::class.java)) moshi.adapter<List<Pair<String, String>>>(Types.newParameterizedType(List::class.java, Pair::class.java, String::class.java, String::class.java))
} }
@TypeConverter @TypeConverter
@ -60,11 +61,11 @@ class Converters {
@TypeConverter @TypeConverter
fun stringPairListToJson(list: List<Pair<String, String>>): String { fun stringPairListToJson(list: List<Pair<String, String>>): String {
return stringMapAdapter.toJson(list.toMap()) return stringListPairAdapter.toJson(list)
} }
@TypeConverter @TypeConverter
fun jsonToStringPairList(value: String): List<Pair<String, String>> { fun jsonToStringPairList(value: String): List<Pair<String, String>> {
return stringMapAdapter.fromJson(value).orEmpty().toList() return stringListPairAdapter.fromJson(value).orEmpty()
} }
} }

View File

@ -0,0 +1,68 @@
package io.github.wulkanowy.data.db.adapters
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
object PairAdapterFactory : JsonAdapter.Factory {
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? {
if (type !is ParameterizedType || List::class.java != type.rawType) return null
if (type.actualTypeArguments[0] != Pair::class.java) return null
val listType = Types.newParameterizedType(List::class.java, Map::class.java, String::class.java)
val listAdapter = moshi.adapter<List<Map<String, String>>>(listType)
val mapType = Types.newParameterizedType(MutableMap::class.java, String::class.java, String::class.java)
val mapAdapter = moshi.adapter<Map<String, String>>(mapType)
return PairAdapter(listAdapter, mapAdapter)
}
private class PairAdapter(
private val listAdapter: JsonAdapter<List<Map<String, String>>>,
private val mapAdapter: JsonAdapter<Map<String, String>>,
) : JsonAdapter<List<Pair<String, String>>>() {
override fun toJson(writer: JsonWriter, value: List<Pair<String, String>>?) {
writer.beginArray()
value?.forEach {
writer.beginObject()
writer.name("first").value(it.first)
writer.name("second").value(it.second)
writer.endObject()
}
writer.endArray()
}
override fun fromJson(reader: JsonReader): List<Pair<String, String>>? {
return if (reader.peek() == JsonReader.Token.BEGIN_OBJECT) deserializeMoshiMap(reader)
else deserializeGsonPair(reader)
}
// for compatibility with 0.21.0
private fun deserializeMoshiMap(reader: JsonReader): List<Pair<String, String>>? {
val map = mapAdapter.fromJson(reader) ?: return null
return map.entries.map {
it.key to it.value
}
}
private fun deserializeGsonPair(reader: JsonReader): List<Pair<String, String>>? {
val list = listAdapter.fromJson(reader) ?: return null
require(list.size == 2 || list.isEmpty()) {
"pair with more or less than two elements: $list"
}
return list.map {
it["first"].orEmpty() to it["second"].orEmpty()
}
}
}
}

View File

@ -0,0 +1,25 @@
package io.github.wulkanowy.data.db
import org.junit.Assert.assertEquals
import org.junit.Test
class ConvertersTest {
@Test
fun stringPairListToJson() {
assertEquals(Converters().stringPairListToJson(listOf("aaa" to "bbb", "ccc" to "ddd")), "[{\"first\":\"aaa\",\"second\":\"bbb\"},{\"first\":\"ccc\",\"second\":\"ddd\"}]")
assertEquals(Converters().stringPairListToJson(listOf()), "[]")
}
@Test
fun jsonToStringPairList() {
assertEquals(Converters().jsonToStringPairList("[{\"first\":\"aaa\",\"second\":\"bbb\"},{\"first\":\"ccc\",\"second\":\"ddd\"}]"), listOf("aaa" to "bbb", "ccc" to "ddd"))
assertEquals(Converters().jsonToStringPairList("[]"), listOf<Pair<String, String>>())
}
@Test
fun jsonToStringPairList_0210() {
assertEquals(Converters().jsonToStringPairList("{\"aaa\":\"bbb\",\"ccc\":\"ddd\"}"), listOf("aaa" to "bbb", "ccc" to "ddd"))
assertEquals(Converters().jsonToStringPairList("{}"), listOf<Pair<String, String>>())
}
}