John O'Reilly
02/12/2022, 10:44 AMJohn O'Reilly
02/12/2022, 10:45 AM"route": {
"1644660208": "635561",
"1644660593": "523441",
"1644660829": "523461",
"1644660900": "523471",
"1644660953": "523481",
"1644660985": "523491"
...
}
John O'Reilly
02/12/2022, 10:45 AMDominaezzz
02/12/2022, 10:59 AMJsonObject
in your custom serializer, then do the conversion in there.John O'Reilly
02/12/2022, 11:02 AMephemient
02/12/2022, 11:51 AM@Serializable
data class MyData(
val route: Map<String, String>
)
val myData = Json.decodeFromString(
MyData.serializer(),
"""
{
"route": {
"1644660208": "635561",
"1644660593": "523441",
"1644660829": "523461",
"1644660900": "523471",
"1644660953": "523481",
"1644660985": "523491"
}
}
""".trimIndent()
)
println(myData) // => MyData(route={1644660208=635561, 1644660593=523441, 1644660829=523461, 1644660900=523471, 1644660953=523481, 1644660985=523491})
unless you go out of your way to use HashMap, the default maps and sets in Kotlin preserve orderJohn O'Reilly
02/12/2022, 11:52 AMephemient
02/12/2022, 12:19 PM@Serializable
data class MyData(
val route: Multimap<String, String>
)
@Serializable(with = Multimap.Serializer::class)
data class Multimap<K, V>(val pairs: List<Pair<K, V>>) {
class Serializer<K, V>(val kSerializer: KSerializer<K>, val vSerializer: KSerializer<V>) : KSerializer<Multimap<K, V>> {
override val descriptor: SerialDescriptor = MapSerializer(kSerializer, vSerializer).descriptor
override fun serialize(encoder: Encoder, value: Multimap<K, V>) {
encoder.encodeCollection(descriptor, value.pairs.size) {
value.pairs.forEachIndexed { i, (k, v) ->
encodeSerializableElement(descriptor, 2 * i, kSerializer, k)
encodeSerializableElement(descriptor, 2 * i + 1, vSerializer, v)
}
}
}
override fun deserialize(decoder: Decoder): Multimap<K, V> {
val pairs = decoder.decodeStructure(descriptor) {
if (decodeSequentially()) {
val size = decodeCollectionSize(descriptor)
List(size / 2) {
val k = decodeSerializableElement(descriptor, 2 * it, kSerializer)
val v = decodeSerializableElement(descriptor, 2 * it + 1, vSerializer)
k to v
}
} else {
buildList {
while (true) {
val i = decodeElementIndex(descriptor)
if (i == CompositeDecoder.DECODE_DONE) break
val k = decodeSerializableElement(descriptor, i, kSerializer)
val j = decodeElementIndex(descriptor)
if (j == CompositeDecoder.DECODE_DONE) throw SerializationException("missing value")
val v = decodeSerializableElement(descriptor, j, vSerializer)
add(k to v)
}
}
}
}
return Multimap(pairs)
}
}
}
val myData = Json.decodeFromString(
MyData.serializer(),
"""
{
"route": {
"1644660208": "635561",
"1644660593": "523441",
"1644660829": "523461",
"1644660900": "523471",
"1644660953": "523481",
"1644660985": "523491",
"1644660208": "635561",
"1644660593": "523441",
"1644660829": "523461",
"1644660900": "523471",
"1644660953": "523481"
}
}
""".trimIndent()
)
println(myData) // => MyData(route=Multimap(pairs=[(1644660208, 635561), (1644660593, 523441), (1644660829, 523461), (1644660900, 523471), (1644660953, 523481), (1644660985, 523491), (1644660208, 635561), (1644660593, 523441), (1644660829, 523461), (1644660900, 523471), (1644660953, 523481)]))
but hopefully that is not what you are dealing with (it's not well-specified by the JSON specification how implementations should handle duplicate keys, and results do vary)Dominaezzz
02/12/2022, 12:21 PMdecodeSequentially
. It'll never happen.Dominaezzz
02/12/2022, 12:22 PMPaul Woitaschek
02/12/2022, 12:54 PMJohn O'Reilly
02/12/2022, 12:54 PMPaul Woitaschek
02/12/2022, 12:55 PMPaul Woitaschek
02/12/2022, 12:55 PMAn object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.
Paul Woitaschek
02/12/2022, 12:55 PMPaul Woitaschek
02/12/2022, 12:59 PMephemient
02/12/2022, 1:05 PMephemient
02/12/2022, 1:06 PMPaul Woitaschek
02/12/2022, 1:14 PMPaul Woitaschek
02/12/2022, 1:16 PMPaul Woitaschek
02/12/2022, 1:18 PMJohn O'Reilly
02/12/2022, 1:19 PMJohn O'Reilly
02/12/2022, 1:20 PMJohn O'Reilly
02/12/2022, 1:21 PMephemient
02/12/2022, 1:21 PMelement as JsonObject
can be just written as element.jsonObject 🙂John O'Reilly
02/12/2022, 1:22 PMobject MapToList : JsonTransformingSerializer<List<String>>(ListSerializer(String.serializer())) {
override fun transformDeserialize(element: JsonElement): JsonElement {
val arrayEntries = element.jsonObject.map { (_, value) -> value }
return JsonArray(arrayEntries)
}
}
Dominaezzz
02/12/2022, 1:22 PMbuildJsonArray { ... }
Paul Woitaschek
02/12/2022, 1:45 PMPaul Woitaschek
02/12/2022, 1:46 PMJohn O'Reilly
02/12/2022, 1:46 PMPaul Woitaschek
02/12/2022, 1:47 PMJohn O'Reilly
02/12/2022, 1:47 PMJohn O'Reilly
02/12/2022, 1:49 PMPaul Woitaschek
02/12/2022, 1:49 PM