From 423efafa0462f76c9fe211b92d1dc674569136e9 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 23 Jan 2020 16:36:25 +0600 Subject: [PATCH] extend polls --- CHANGELOG.md | 5 + .../TelegramBotAPI/types/Common.kt | 6 + .../TelegramBotAPI/types/polls/Poll.kt | 107 ++++++++++++++++-- 3 files changed, 110 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d509ed93f..15d384b7b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## 0.23.0 TelegramBotAPI 4.6 +* `Poll` now is sealed class + * `RegularPoll` type was added to represent polls with type `regular` + * `QuizPoll` type was added to represent polls with type `quiz` + * `UnknownPollType` type was added to represent polls which are unknown in current version + ## 0.22.0 * **`KtorCallFactory` must return `HttpStatement` instead of `HttpClientCall`** diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt index 873e7c49de..906ea75281 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt @@ -90,6 +90,9 @@ const val lastErrorDateField = "last_error_date" const val lastErrorMessageField = "last_error_message" const val votesCountField = "voter_count" const val isClosedField = "is_closed" +const val correctOptionIdField = "correct_option_id" +const val allowsMultipleAnswersField = "allows_multiple_answers" +const val isAnonymousField = "is_anonymous" const val loginUrlField = "login_url" const val forwardTextField = "forward_text" const val botUsernameField = "bot_username" @@ -273,3 +276,6 @@ const val mediaField = "media" const val disableEditMessageField = "disable_edit_message" const val scoreField = "score" const val forceField = "force" + +const val regularPollType = "regular" +const val quizPollType = "quiz" diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/polls/Poll.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/polls/Poll.kt index 5d15b1a762..d65df26aa6 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/polls/Poll.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/polls/Poll.kt @@ -1,17 +1,108 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.polls import com.github.insanusmokrassar.TelegramBotAPI.types.* -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable +import kotlinx.serialization.* +import kotlinx.serialization.internal.ArrayListSerializer +import kotlinx.serialization.json.* + +@Serializable(PollSerializer::class) +sealed class Poll { + abstract val id: PollIdentifier + abstract val question: String + abstract val options: List + abstract val closed: Boolean + abstract val isAnonymous: Boolean +} @Serializable -data class Poll( +data class UnknownPollType( @SerialName(idField) - val id: PollIdentifier, + override val id: PollIdentifier, @SerialName(questionField) - val question: String, + override val question: String, @SerialName(optionsField) - val options: List, + override val options: List, @SerialName(isClosedField) - val closed: Boolean = false -) + override val closed: Boolean = false, + @SerialName(isAnonymousField) + override val isAnonymous: Boolean = false, + val raw: String +) : Poll() + +@Serializable +data class RegularPoll( + @SerialName(idField) + override val id: PollIdentifier, + @SerialName(questionField) + override val question: String, + @SerialName(optionsField) + override val options: List, + @SerialName(isClosedField) + override val closed: Boolean = false, + @SerialName(isAnonymousField) + override val isAnonymous: Boolean = false, + @SerialName(allowsMultipleAnswersField) + val allowMultipleAnswers: Boolean = false +) : Poll() + +@Serializable +data class QuizPoll( + @SerialName(idField) + override val id: PollIdentifier, + @SerialName(questionField) + override val question: String, + @SerialName(optionsField) + override val options: List, + @SerialName(isClosedField) + override val closed: Boolean = false, + @SerialName(isAnonymousField) + override val isAnonymous: Boolean = false, + @SerialName(correctOptionIdField) + val correctOptionId: Boolean = false +) : Poll() + +@Serializer(Poll::class) +internal object PollSerializer : KSerializer { + private val pollOptionsSerializer = ArrayListSerializer(PollOption.serializer()) + override fun deserialize(decoder: Decoder): Poll { + val asJson = JsonObjectSerializer.deserialize(decoder) + + return when (asJson.getPrimitive(typeField).content) { + regularPollType -> Json.nonstrict.fromJson( + RegularPoll.serializer(), + asJson + ) + quizPollType -> Json.nonstrict.fromJson( + QuizPoll.serializer(), + asJson + ) + else -> UnknownPollType( + asJson.getPrimitive(idField).content, + asJson.getPrimitive(questionField).content, + Json.nonstrict.fromJson( + pollOptionsSerializer, + asJson.getArray(optionsField) + ), + asJson.getPrimitiveOrNull(isClosedField) ?.booleanOrNull ?: false, + asJson.getPrimitiveOrNull(isAnonymousField) ?.booleanOrNull ?: true, + asJson.toString() + ) + } + } + + override fun serialize(encoder: Encoder, obj: Poll) { + val asJson = when (obj) { + is RegularPoll -> Json.nonstrict.toJson(RegularPoll.serializer(), obj) + is QuizPoll -> Json.nonstrict.toJson(QuizPoll.serializer(), obj) + is UnknownPollType -> throw IllegalArgumentException("Currently unable to correctly serialize object of poll $obj") + } + val resultJson = JsonObject( + asJson.jsonObject + (typeField to when (obj) { + is RegularPoll -> JsonPrimitive(regularPollType) + is QuizPoll -> JsonPrimitive(quizPollType) + is UnknownPollType -> throw IllegalArgumentException("Currently unable to correctly serialize object of poll $obj") + }) + ) + JsonObjectSerializer.serialize(encoder, resultJson) + } +}