Skip to content

Commit

Permalink
Replace companion object serializers (#869)
Browse files Browse the repository at this point in the history
* Update serializer for DiscordShard

The companion object is no longer the serializer and the implementation
was changed to work with IntArray instead of JsonArray.

* Update serializer for Heartbeat

The companion object is no longer the serializer.

* Update serializer for OpCode

The companion object is no longer the serializer.
  • Loading branch information
lukellmann authored Sep 17, 2023
1 parent 1b95322 commit d918920
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 41 deletions.
5 changes: 5 additions & 0 deletions common/api/common.api
Original file line number Diff line number Diff line change
Expand Up @@ -5738,6 +5738,7 @@ public final class dev/kord/common/entity/DiscordSelectOption$Companion {

public final class dev/kord/common/entity/DiscordShard {
public static final field Companion Ldev/kord/common/entity/DiscordShard$Companion;
public static final field NewCompanion Ldev/kord/common/entity/DiscordShard$NewCompanion;
public fun <init> (II)V
public final fun component1 ()I
public final fun component2 ()I
Expand All @@ -5759,6 +5760,10 @@ public final class dev/kord/common/entity/DiscordShard$Companion : kotlinx/seria
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class dev/kord/common/entity/DiscordShard$NewCompanion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class dev/kord/common/entity/DiscordStageInstance {
public static final field Companion Ldev/kord/common/entity/DiscordStageInstance$Companion;
public synthetic fun <init> (ILdev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/common/entity/StageInstancePrivacyLevel;ZLdev/kord/common/entity/Snowflake;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
Expand Down
53 changes: 34 additions & 19 deletions common/src/commonMain/kotlin/entity/DiscordShard.kt
Original file line number Diff line number Diff line change
@@ -1,39 +1,54 @@
package dev.kord.common.entity

import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.builtins.IntArraySerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
import kotlin.jvm.JvmField

/**
* An instance of a [Discord shard](https://discord.com/developers/docs/topics/gateway#sharding).
*/
@Serializable(with = DiscordShard.Companion::class)
@Serializable(with = DiscordShard.Serializer::class)
public data class DiscordShard(val index: Int, val count: Int) {

public companion object : KSerializer<DiscordShard> {

internal object Serializer : KSerializer<DiscordShard> {
@OptIn(ExperimentalSerializationApi::class)
override val descriptor: SerialDescriptor
get() = listSerialDescriptor(PrimitiveSerialDescriptor("DiscordShardElement", PrimitiveKind.INT))
override val descriptor =
SerialDescriptor("dev.kord.common.entity.DiscordShard", original = IntArraySerializer().descriptor)

override fun serialize(encoder: Encoder, value: DiscordShard) {
val array = buildJsonArray {
add(JsonPrimitive(value.index))
add(JsonPrimitive(value.count))
}

encoder.encodeSerializableValue(JsonArray.serializer(), array)
val array = intArrayOf(value.index, value.count)
encoder.encodeSerializableValue(IntArraySerializer(), array)
}

override fun deserialize(decoder: Decoder): DiscordShard {
val array = JsonArray.serializer().deserialize(decoder)
val index = array[0].jsonPrimitive.int
val count = array[1].jsonPrimitive.int
return DiscordShard(index, count)
val array = decoder.decodeSerializableValue(IntArraySerializer())
if (array.size != 2) throw SerializationException("Expected IntArray with exactly two elements")
return DiscordShard(index = array[0], count = array[1])
}
}

public companion object NewCompanion {
@Suppress("DEPRECATION")
@Deprecated(
"Renamed to 'NewCompanion', which no longer implements 'KSerializer<DiscordShard>'.",
ReplaceWith("DiscordShard.serializer()", imports = ["dev.kord.common.entity.DiscordShard"]),
DeprecationLevel.WARNING,
)
@JvmField
public val Companion: Companion = Companion()
}

@Deprecated(
"Renamed to 'NewCompanion', which no longer implements 'KSerializer<DiscordShard>'.",
ReplaceWith("DiscordShard.serializer()", imports = ["dev.kord.common.entity.DiscordShard"]),
DeprecationLevel.WARNING,
)
public class Companion internal constructor() : KSerializer<DiscordShard> by Serializer {
public fun serializer(): KSerializer<DiscordShard> = this
}
}
10 changes: 10 additions & 0 deletions gateway/api/gateway.api
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,7 @@ public final class dev/kord/gateway/GuildUpdate : dev/kord/gateway/DispatchEvent

public final class dev/kord/gateway/Heartbeat : dev/kord/gateway/Event {
public static final field Companion Ldev/kord/gateway/Heartbeat$Companion;
public static final field NewCompanion Ldev/kord/gateway/Heartbeat$NewCompanion;
public fun <init> (J)V
public final fun component1 ()J
public final fun copy (J)Ldev/kord/gateway/Heartbeat;
Expand All @@ -1048,6 +1049,10 @@ public final class dev/kord/gateway/Heartbeat$Companion : kotlinx/serialization/
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class dev/kord/gateway/Heartbeat$NewCompanion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class dev/kord/gateway/HeartbeatACK : dev/kord/gateway/Event {
public static final field INSTANCE Ldev/kord/gateway/HeartbeatACK;
}
Expand Down Expand Up @@ -1535,6 +1540,7 @@ public final class dev/kord/gateway/MessageUpdate : dev/kord/gateway/DispatchEve
}

public final class dev/kord/gateway/OpCode : java/lang/Enum {
public static final field Companion Ldev/kord/gateway/OpCode$Companion;
public static final field Dispatch Ldev/kord/gateway/OpCode;
public static final field Heartbeat Ldev/kord/gateway/OpCode;
public static final field HeartbeatACK Ldev/kord/gateway/OpCode;
Expand All @@ -1554,6 +1560,10 @@ public final class dev/kord/gateway/OpCode : java/lang/Enum {
public static fun values ()[Ldev/kord/gateway/OpCode;
}

public final class dev/kord/gateway/OpCode$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class dev/kord/gateway/OpCode$OpCodeSerializer : kotlinx/serialization/KSerializer {
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ldev/kord/gateway/OpCode;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
Expand Down
32 changes: 24 additions & 8 deletions gateway/src/commonMain/kotlin/Event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import mu.KotlinLogging
import kotlin.jvm.JvmField
import kotlinx.serialization.DeserializationStrategy as KDeserializationStrategy

private val jsonLogger = KotlinLogging.logger { }
Expand Down Expand Up @@ -582,17 +583,32 @@ public data class ReadyData(
val shard: Optional<DiscordShard> = Optional.Missing(),
)

@Serializable(with = Heartbeat.Companion::class)
@Serializable(with = Heartbeat.Serializer::class)
public data class Heartbeat(val data: Long) : Event() {
public companion object : KSerializer<Heartbeat> {
override val descriptor: SerialDescriptor
get() = PrimitiveSerialDescriptor("HeartbeatEvent", PrimitiveKind.LONG)
internal object Serializer : KSerializer<Heartbeat> {
override val descriptor = PrimitiveSerialDescriptor("dev.kord.gateway.Heartbeat", PrimitiveKind.LONG)
override fun serialize(encoder: Encoder, value: Heartbeat) = encoder.encodeLong(value.data)
override fun deserialize(decoder: Decoder) = Heartbeat(decoder.decodeLong())
}

override fun deserialize(decoder: Decoder): Heartbeat = Heartbeat(decoder.decodeLong())
public companion object NewCompanion {
@Suppress("DEPRECATION")
@Deprecated(
"Renamed to 'NewCompanion', which no longer implements 'KSerializer<Heartbeat>'.",
ReplaceWith("Heartbeat.serializer()", imports = ["dev.kord.gateway.Heartbeat"]),
DeprecationLevel.WARNING,
)
@JvmField
public val Companion: Companion = Companion()
}

override fun serialize(encoder: Encoder, value: Heartbeat) {
encoder.encodeLong(value.data)
}
@Deprecated(
"Renamed to 'NewCompanion', which no longer implements 'KSerializer<Heartbeat>'.",
ReplaceWith("Heartbeat.serializer()", imports = ["dev.kord.gateway.Heartbeat"]),
DeprecationLevel.WARNING,
)
public class Companion internal constructor() : KSerializer<Heartbeat> by Serializer {
public fun serializer(): KSerializer<Heartbeat> = this
}
}

Expand Down
39 changes: 25 additions & 14 deletions gateway/src/commonMain/kotlin/OpCode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlin.jvm.JvmField

@Serializable(with = OpCode.OpCodeSerializer::class)
@Serializable(with = OpCode.Serializer::class)
public enum class OpCode(public val code: Int) {
/** The default code for unknown values. */
Unknown(Int.MIN_VALUE),
Expand Down Expand Up @@ -68,19 +68,30 @@ public enum class OpCode(public val code: Int) {
*/
HeartbeatACK(11);

public companion object OpCodeSerializer : KSerializer<OpCode> {
override val descriptor: SerialDescriptor
get() = PrimitiveSerialDescriptor("op", PrimitiveKind.INT)

internal object Serializer : KSerializer<OpCode> {
override val descriptor = PrimitiveSerialDescriptor("dev.kord.gateway.OpCode", PrimitiveKind.INT)
override fun serialize(encoder: Encoder, value: OpCode) = encoder.encodeInt(value.code)
private val entriesByCode = entries.associateBy { it.code }
override fun deserialize(decoder: Decoder): OpCode {
val code = decoder.decodeInt()
return entriesByCode[code] ?: Unknown
}

override fun serialize(encoder: Encoder, value: OpCode) {
encoder.encodeInt(value.code)
}
override fun deserialize(decoder: Decoder) = entriesByCode[decoder.decodeInt()] ?: Unknown
}

public companion object {
@Suppress("DEPRECATION")
@Deprecated(
"Renamed to 'Companion', which no longer implements 'KSerializer<OpCode>'.",
ReplaceWith("OpCode.serializer()", imports = ["dev.kord.gateway.OpCode"]),
DeprecationLevel.WARNING,
)
@JvmField
public val OpCodeSerializer: OpCodeSerializer = OpCodeSerializer()
}

@Deprecated(
"Renamed to 'Companion', which no longer implements 'KSerializer<OpCode>'.",
ReplaceWith("OpCode.serializer()", imports = ["dev.kord.gateway.OpCode"]),
DeprecationLevel.WARNING,
)
public class OpCodeSerializer internal constructor() : KSerializer<OpCode> by Serializer {
public fun serializer(): KSerializer<OpCode> = this
}
}

0 comments on commit d918920

Please sign in to comment.