diff --git a/tgbotapi.core/api/tgbotapi.core.api b/tgbotapi.core/api/tgbotapi.core.api index 1e96a1c912..72a790f650 100644 --- a/tgbotapi.core/api/tgbotapi.core.api +++ b/tgbotapi.core/api/tgbotapi.core.api @@ -8451,6 +8451,7 @@ public final class dev/inmo/tgbotapi/types/CommonKt { public static final field temporaryRegistrationField Ljava/lang/String; public static final field textEntitiesField Ljava/lang/String; public static final field textField Ljava/lang/String; + public static final field textParseModeField Ljava/lang/String; public static final field tgWebAppStartParamField Ljava/lang/String; public static final field tgsStickerField Ljava/lang/String; public static final field themeNameField Ljava/lang/String; @@ -23544,23 +23545,23 @@ public final class dev/inmo/tgbotapi/types/polls/SimplePollOption$Companion { public final class dev/inmo/tgbotapi/types/polls/UnknownPollType : dev/inmo/tgbotapi/types/polls/Poll { public static final field Companion Ldev/inmo/tgbotapi/types/polls/UnknownPollType$Companion; - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;IZZLkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILjava/util/List;ZZLkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1-S5FO_mE ()Ljava/lang/String; public final fun component2 ()Ljava/lang/String; public final fun component3 ()Ljava/util/List; - public final fun component4 ()Ljava/util/List; - public final fun component5 ()I + public final fun component4 ()I + public final fun component5 ()Ljava/util/List; public final fun component6 ()Z public final fun component7 ()Z - public final fun component8 ()Lkotlinx/serialization/json/JsonObject; - public final fun copy-KILYFNk (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;IZZLkotlinx/serialization/json/JsonObject;)Ldev/inmo/tgbotapi/types/polls/UnknownPollType; - public static synthetic fun copy-KILYFNk$default (Ldev/inmo/tgbotapi/types/polls/UnknownPollType;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;IZZLkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/polls/UnknownPollType; + public final fun component8 ()Lkotlinx/serialization/json/JsonElement; + public final fun copy-KILYFNk (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILjava/util/List;ZZLkotlinx/serialization/json/JsonElement;)Ldev/inmo/tgbotapi/types/polls/UnknownPollType; + public static synthetic fun copy-KILYFNk$default (Ldev/inmo/tgbotapi/types/polls/UnknownPollType;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILjava/util/List;ZZLkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/polls/UnknownPollType; public fun equals (Ljava/lang/Object;)Z public fun getId-S5FO_mE ()Ljava/lang/String; public fun getOptions ()Ljava/util/List; public fun getQuestion ()Ljava/lang/String; public fun getQuestionTextSources ()Ljava/util/List; - public final fun getRaw ()Lkotlinx/serialization/json/JsonObject; + public final fun getRaw ()Lkotlinx/serialization/json/JsonElement; public fun getScheduledCloseInfo ()Ldev/inmo/tgbotapi/types/polls/ScheduledCloseInfo; public fun getText ()Ljava/lang/String; public fun getTextSources ()Ljava/util/List; @@ -25201,7 +25202,7 @@ public final class dev/inmo/tgbotapi/utils/EntitiesBuilderKt { } public final class dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoderKt { - public static final fun extractDataAndJson (Lkotlinx/serialization/encoding/Decoder;Lkotlinx/serialization/DeserializationStrategy;)Lkotlin/Pair; + public static final fun decodeDataAndJson (Lkotlinx/serialization/encoding/Decoder;Lkotlinx/serialization/DeserializationStrategy;)Lkotlin/Pair; } public final class dev/inmo/tgbotapi/utils/IntProgress100Serializer : kotlinx/serialization/KSerializer { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundFill.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundFill.kt index 0b344ae946..a6e19c4cff 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundFill.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundFill.kt @@ -2,15 +2,13 @@ package dev.inmo.tgbotapi.types import dev.inmo.micro_utils.colors.common.HEXAColor import dev.inmo.tgbotapi.utils.IntRGB24HEXAColorSerializer -import dev.inmo.tgbotapi.utils.extractDataAndJson +import dev.inmo.tgbotapi.utils.decodeDataAndJson import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded import kotlinx.serialization.* import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.decodeFromJsonElement @ClassCastsIncluded @Serializable(BackgroundFill.Companion::class) @@ -100,7 +98,7 @@ sealed interface BackgroundFill { get() = serializer.descriptor override fun deserialize(decoder: Decoder): BackgroundFill { - val (raw, json) = decoder.extractDataAndJson(serializer) + val (raw, json) = decoder.decodeDataAndJson(serializer) return when (raw.type) { Solid.type -> Solid(color = raw.color ?: return Unknown(raw.type, json)) Gradient.type -> Gradient( diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundType.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundType.kt index d72361439f..a0d4ad891c 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundType.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundType.kt @@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.types import dev.inmo.micro_utils.common.Progress import dev.inmo.tgbotapi.types.files.DocumentFile import dev.inmo.tgbotapi.utils.IntProgress100Serializer -import dev.inmo.tgbotapi.utils.extractDataAndJson +import dev.inmo.tgbotapi.utils.decodeDataAndJson import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded import kotlinx.serialization.EncodeDefault import kotlinx.serialization.KSerializer @@ -138,7 +138,7 @@ sealed interface BackgroundType { get() = RawBackgroundType.serializer().descriptor override fun deserialize(decoder: Decoder): BackgroundType { - val (raw, json) = decoder.extractDataAndJson(RawBackgroundType.serializer()) + val (raw, json) = decoder.decodeDataAndJson(RawBackgroundType.serializer()) val unknown by lazy { Unknown(raw.type, json) } return when (raw.type) { Fill.type -> Fill( diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt index 8f20fa5cd7..542339a84f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt @@ -163,6 +163,7 @@ const val canReplyField = "can_reply" const val supportInlineQueriesField = "supports_inline_queries" const val canConnectToBusinessField = "can_connect_to_business" const val textEntitiesField = "text_entities" +const val textParseModeField = "text_parse_mode" const val entitiesField = "entities" const val stickerSetNameField = "set_name" const val customEmojiIdField = "custom_emoji_id" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/InputPollOption.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/InputPollOption.kt index cc94c8abc9..1f361f868a 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/InputPollOption.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/InputPollOption.kt @@ -7,10 +7,14 @@ import dev.inmo.tgbotapi.types.message.RawMessageEntity import dev.inmo.tgbotapi.types.message.asTextSources import dev.inmo.tgbotapi.types.message.textsources.TextSource import dev.inmo.tgbotapi.types.message.toRawMessageEntities +import dev.inmo.tgbotapi.types.textEntitiesField +import dev.inmo.tgbotapi.types.textField +import dev.inmo.tgbotapi.types.textParseModeField import dev.inmo.tgbotapi.utils.EntitiesBuilder import dev.inmo.tgbotapi.utils.EntitiesBuilderBody import dev.inmo.tgbotapi.utils.extensions.makeSourceString import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder @@ -18,8 +22,11 @@ import kotlinx.serialization.encoding.Encoder @Serializable(InputPollOption.Companion::class) data class InputPollOption @Warning("This constructor is not recommended to use") constructor( + @SerialName(textField) override val text: String, + @SerialName(textParseModeField) val parseMode: ParseMode?, + @SerialName(textEntitiesField) override val textSources: List, ) : TextedInput { constructor(text: String, parseMode: ParseMode? = null) : this(text, parseMode, emptyList()) @@ -29,8 +36,11 @@ data class InputPollOption @Warning("This constructor is not recommended to use" companion object : KSerializer { @Serializable private data class RawPollInputOption( + @SerialName(textField) val text: String, + @SerialName(textParseModeField) val parseMode: ParseMode? = null, + @SerialName(textEntitiesField) val textSources: List = emptyList(), ) override val descriptor: SerialDescriptor diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt index a3ea25780f..08e11141f2 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt @@ -10,7 +10,7 @@ import dev.inmo.tgbotapi.types.message.RawMessageEntity import dev.inmo.tgbotapi.types.message.textsources.TextSource import dev.inmo.tgbotapi.types.message.toRawMessageEntities import dev.inmo.tgbotapi.utils.RiskFeature -import dev.inmo.tgbotapi.utils.nonstrictJsonFormat +import dev.inmo.tgbotapi.utils.decodeDataAndJson import korlibs.time.seconds import kotlinx.serialization.* import kotlinx.serialization.descriptors.SerialDescriptor @@ -74,12 +74,12 @@ private class RawPoll( val id: PollId, @SerialName(questionField) val question: String, - @SerialName(questionEntitiesField) - val questionEntities: List, @SerialName(optionsField) val options: List, @SerialName(totalVoterCountField) val votesCount: Int, + @SerialName(questionEntitiesField) + val questionEntities: List = emptyList(), @SerialName(isClosedField) val isClosed: Boolean = false, @SerialName(isAnonymousField) @@ -110,24 +110,26 @@ data class UnknownPollType internal constructor( override val id: PollId, @SerialName(questionField) override val question: String, - @SerialName(questionEntitiesField) - override val textSources: List = emptyList(), @SerialName(optionsField) override val options: List, @SerialName(totalVoterCountField) override val votesCount: Int, + @SerialName(questionEntitiesField) + override val textSources: List = emptyList(), @SerialName(isClosedField) override val isClosed: Boolean = false, @SerialName(isAnonymousField) override val isAnonymous: Boolean = false, @Serializable - val raw: JsonObject + val raw: JsonElement? = null ) : Poll { @Transient - override val scheduledCloseInfo: ScheduledCloseInfo? = (raw[closeDateField] ?: raw[openPeriodField]) - ?.jsonPrimitive - ?.longOrNull - ?.asApproximateScheduledCloseInfo + override val scheduledCloseInfo: ScheduledCloseInfo? = raw ?.jsonObject ?.let { + (it[closeDateField] ?: it[openPeriodField]) + ?.jsonPrimitive + ?.longOrNull + ?.asApproximateScheduledCloseInfo + } } @Serializable(PollSerializer::class) @@ -167,8 +169,7 @@ object PollSerializer : KSerializer { get() = RawPoll.serializer().descriptor override fun deserialize(decoder: Decoder): Poll { - val asJson = JsonObject.serializer().deserialize(decoder) - val rawPoll = nonstrictJsonFormat.decodeFromJsonElement(RawPoll.serializer(), asJson) + val (rawPoll, asJson) = decoder.decodeDataAndJson(RawPoll.serializer()) return when (rawPoll.type) { quizPollType -> QuizPoll( @@ -198,9 +199,9 @@ object PollSerializer : KSerializer { else -> UnknownPollType( rawPoll.id, rawPoll.question, - rawPoll.questionEntities.asTextSources(rawPoll.question), rawPoll.options, rawPoll.votesCount, + rawPoll.questionEntities.asTextSources(rawPoll.question), rawPoll.isClosed, rawPoll.isAnonymous, asJson @@ -214,9 +215,9 @@ object PollSerializer : KSerializer { is RegularPoll -> RawPoll( value.id, value.question, - value.textSources.toRawMessageEntities(), value.options, value.votesCount, + value.textSources.toRawMessageEntities(), value.isClosed, value.isAnonymous, regularPollType, @@ -227,9 +228,9 @@ object PollSerializer : KSerializer { is QuizPoll -> RawPoll( value.id, value.question, - value.textSources.toRawMessageEntities(), value.options, value.votesCount, + value.textSources.toRawMessageEntities(), value.isClosed, value.isAnonymous, regularPollType, @@ -240,7 +241,11 @@ object PollSerializer : KSerializer { closeDate = (closeInfo as? ExactScheduledCloseInfo) ?.closeDateTime ?.unixMillisLong ?.div(1000L) ) is UnknownPollType -> { - JsonObject.serializer().serialize(encoder, value.raw) + if (value.raw == null) { + UnknownPollType.serializer().serialize(encoder, value) + } else { + JsonElement.serializer().serialize(encoder, value.raw) + } return } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/PollOption.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/PollOption.kt index ed5550741f..e3293e3e37 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/PollOption.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/PollOption.kt @@ -48,7 +48,7 @@ data class SimplePollOption ( @SerialName(textField) override val text: String, @SerialName(textEntitiesField) - override val textSources: List, + override val textSources: List = emptyList(), @SerialName(votesCountField) override val votes: Int = 0 ) : PollOption() { @@ -62,7 +62,7 @@ object PollOptionSerializer : KSerializer { @SerialName(textField) val text: String, @SerialName(textEntitiesField) - val textSources: List, + val textSources: List = emptyList(), @SerialName(votesCountField) val votes: Int = 0 ) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoder.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoder.kt index 518c417810..f88ba10613 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoder.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoder.kt @@ -5,7 +5,7 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonElement -fun Decoder.extractDataAndJson(serializer: DeserializationStrategy): Pair { +fun Decoder.decodeDataAndJson(serializer: DeserializationStrategy): Pair { return if (this is JsonDecoder) { val raw = decodeJsonElement() json.decodeFromJsonElement(serializer, raw) to raw diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/raw/Poll.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/raw/Poll.kt index 97ece7e16b..45210be512 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/raw/Poll.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/raw/Poll.kt @@ -6,6 +6,7 @@ import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList import dev.inmo.tgbotapi.types.polls.* import dev.inmo.tgbotapi.utils.RiskFeature import korlibs.time.seconds +import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive @RiskFeature(RawFieldsUsageWarning) @@ -15,7 +16,7 @@ val Poll.total_voter_count: Int val Poll.type: String get() = when (this) { is RegularPoll -> "regular" - is UnknownPollType -> raw["type"]!!.jsonPrimitive.content + is UnknownPollType -> raw!!.jsonObject["type"]!!.jsonPrimitive.content is QuizPoll -> "quiz" } @RiskFeature(RawFieldsUsageWarning)