zt
01/14/2023, 6:06 AM@Serializable
internal enum class ChannelTab {
@SerialName("videos")
VIDEOS,
@SerialName("shorts")
SHORTS,
@SerialName("live")
LIVE,
@SerialName("playlists")
PLAYLISTS,
@SerialName("community")
COMMUNITY,
@SerialName("about")
ABOUT
}
@Serializable
internal data class ChannelParams(
@ProtoNumber(2)
val tab: ChannelTab
)
ephemient
01/14/2023, 7:44 AMephemient
01/14/2023, 7:45 AM@Serializable
data class ChannelParams(
@ProtoNumber(2)
val tab: EnumWrapper<ChannelTab>
)
@Serializable(with = EnumWrapperSerializer::class)
data class EnumWrapper<E : Enum<E>>(val enum: E)
class EnumWrapperSerializer<E : Enum<E>>(private val enumSerializer: KSerializer<E>) : KSerializer<EnumWrapper<E>> {
init {
require(enumSerializer.descriptor.kind == SerialKind.ENUM)
}
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor(enumSerializer.descriptor.serialName, PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: EnumWrapper<E>) {
encoder.encodeString(enumSerializer.descriptor.getElementName(value.enum.ordinal))
}
override fun deserialize(decoder: Decoder): EnumWrapper<E> {
val ordinal = enumSerializer.descriptor.getElementIndex(decoder.decodeString())
return EnumWrapper(enumSerializer.deserialize(object : Decoder {
override val serializersModule: SerializersModule = EmptySerializersModule()
override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder =
throw UnsupportedOperationException()
override fun decodeBoolean(): Boolean = throw UnsupportedOperationException()
override fun decodeByte(): Byte = throw UnsupportedOperationException()
override fun decodeChar(): Char = throw UnsupportedOperationException()
override fun decodeDouble(): Double = throw UnsupportedOperationException()
override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = ordinal
override fun decodeFloat(): Float = throw UnsupportedOperationException()
override fun decodeInline(descriptor: SerialDescriptor): Decoder = throw UnsupportedOperationException()
override fun decodeInt(): Int = throw UnsupportedOperationException()
override fun decodeLong(): Long = throw UnsupportedOperationException()
override fun decodeNotNullMark(): Boolean = throw UnsupportedOperationException()
override fun decodeNull(): Nothing? = throw UnsupportedOperationException()
override fun decodeShort(): Short = throw UnsupportedOperationException()
override fun decodeString(): String = throw UnsupportedOperationException()
}))
}
}
zt
01/15/2023, 6:06 AMephemient
01/15/2023, 6:16 AMephemient
01/15/2023, 6:24 AMclass EnumAsStringSerializer<E : Enum<E>>(enumClass: Class<E>) : KSerializer<E> {
private val namesByValue = requireNotNull(enumClass.enumConstants)
.associateWith { enumClass.getField(it.name).getAnnotation(SerialName::class.java)?.value ?: it.name }
private val valuesByName = namesByValue.entries.associateBy(keySelector = { it.value }, valueTransform = { it.key })
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(enumClass.name, PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: E) {
encoder.encodeString(namesByValue.getValue(value))
}
override fun deserialize(decoder: Decoder): E = valuesByName.getValue(decoder.decodeString())
}
@Serializable(with = ChannelTab.Serializer::class)
enum class ChannelTab {
@SerialName("videos") VIDEOS,
// etc.
;
object Serializer : KSerializer<ChannelTab> by EnumAsStringSerializer(ChannelTab::class.java)
}
(although I haven't tested that either)zt
01/15/2023, 7:04 AMephemient
01/15/2023, 7:24 AMclass EnumAsStringSerializer<E : Enum<E>>(private val enumSerializer: KSerializer<E>) : KSerializer<E> {
// basically the same as EnumWrapperSerializer previously, just without EnumWrapper
}
@Serializable(with = ChannelTab.StringSerializer::class)
enum class ChannelTab {
...;
@Serializer(forClass = ChannelTab)
object EnumSerializer
object StringSerializer : KSerializer<ChannelTab> by EnumAsStringSerializer(EnumSerializer)
}
but it's pretty ugly either wayephemient
01/15/2023, 8:37 AMclass EnumAsStringSerializer<E : Enum<E>>(private val enumSerializer: KSerializer<E>) : KSerializer<E> {
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor(enumSerializer.descriptor.serialName, PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: E) {
encoder.encodeString(Json.encodeToJsonElement(enumSerializer, value).jsonPrimitive.content)
}
override fun deserialize(decoder: Decoder): E =
Json.decodeFromJsonElement(enumSerializer, JsonPrimitive(decoder.decodeString()))
}
zt
01/15/2023, 6:45 PM