resolution of #484

This commit is contained in:
InsanusMokrassar 2021-10-18 14:45:57 +06:00
parent 65c1f018ac
commit 91212eaa3a
25 changed files with 86 additions and 45 deletions

View File

@ -24,10 +24,13 @@
* Two new dsl: * Two new dsl:
* `inlineKeyboard` for creating `InlineKeyboardMarkup` * `inlineKeyboard` for creating `InlineKeyboardMarkup`
* `replyKeyboard` for creating `ReplyKeyboardMarkup` * `replyKeyboard` for creating `ReplyKeyboardMarkup`
* Cast helpers for `Message`: * Cast helpers for `Message` (thanks to [madhead](https://github.com/madhead)):
* `asPossiblyReplyMessage`: tries to cast a `Message` to `PossiblyReplyMessage`, returns `null` if the message is not of that type * `asPossiblyReplyMessage`: tries to cast a `Message` to `PossiblyReplyMessage`, returns `null` if the message is not of that type
* `requirePossiblyReplyMessage`: casts a `Message` to `PossiblyReplyMessage`, fails if the message is not of that type * `requirePossiblyReplyMessage`: casts a `Message` to `PossiblyReplyMessage`, fails if the message is not of that type
* `whenPossiblyReplyMessage`: tries to cast a `Message` to `PossiblyReplyMessage` and runs the given block of code with it, if the cast is successful * `whenPossiblyReplyMessage`: tries to cast a `Message` to `PossiblyReplyMessage` and runs the given block of code with it, if the cast is successful
* New type `WithUser` for unioning of all types with `user`
* `FromUser` now extends `WithUser`
* Cast helpers for type `WithUser`: `asWithUser`, `whenWithUser`, `requireWithUser`
* `Behaviour Builder`: * `Behaviour Builder`:
* New expecters and waiters: * New expecters and waiters:
* `waitShippingQueries`/`onShippingQuery` * `waitShippingQueries`/`onShippingQuery`

View File

@ -2,6 +2,15 @@ package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.types.User
interface FromUser { /**
val user: User * Inheritors of this interface have some [User] as a source of data. For example, any [dev.inmo.tgbotapi.types.CallbackQuery.CallbackQuery]
} * have [User] as the source of that query
*/
interface FromUser : WithUser {
/**
* The source [User] of this type
*/
val from: User
override val user: User
get() = from
}

View File

@ -0,0 +1,12 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.User
/**
* All inheritors of this type have [User] in their data as one of the main data
*
* @see FromUser
*/
interface WithUser {
val user: User
}

View File

@ -11,7 +11,7 @@ sealed interface CallbackQuery : FromUser {
data class UnknownCallbackQueryType( data class UnknownCallbackQueryType(
override val id: CallbackQueryIdentifier, override val id: CallbackQueryIdentifier,
override val user: User, override val from: User,
override val chatInstance: String, override val chatInstance: String,
val raw: String val raw: String
) : CallbackQuery ) : CallbackQuery

View File

@ -4,7 +4,7 @@ import dev.inmo.tgbotapi.types.*
data class InlineMessageIdDataCallbackQuery( data class InlineMessageIdDataCallbackQuery(
override val id: CallbackQueryIdentifier, override val id: CallbackQueryIdentifier,
override val user: User, override val from: User,
override val chatInstance: String, override val chatInstance: String,
override val inlineMessageId: InlineMessageIdentifier, override val inlineMessageId: InlineMessageIdentifier,
override val data: String override val data: String

View File

@ -4,7 +4,7 @@ import dev.inmo.tgbotapi.types.*
data class InlineMessageIdGameShortNameCallbackQuery( data class InlineMessageIdGameShortNameCallbackQuery(
override val id: CallbackQueryIdentifier, override val id: CallbackQueryIdentifier,
override val user: User, override val from: User,
override val chatInstance: String, override val chatInstance: String,
override val inlineMessageId: InlineMessageIdentifier, override val inlineMessageId: InlineMessageIdentifier,
override val gameShortName: String override val gameShortName: String

View File

@ -6,7 +6,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.Message
data class MessageDataCallbackQuery( data class MessageDataCallbackQuery(
override val id: CallbackQueryIdentifier, override val id: CallbackQueryIdentifier,
override val user: User, override val from: User,
override val chatInstance: String, override val chatInstance: String,
override val message: Message, override val message: Message,
override val data: String override val data: String

View File

@ -6,7 +6,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.Message
data class MessageGameShortNameCallbackQuery( data class MessageGameShortNameCallbackQuery(
override val id: CallbackQueryIdentifier, override val id: CallbackQueryIdentifier,
override val user: User, override val from: User,
override val chatInstance: String, override val chatInstance: String,
override val message: Message, override val message: Message,
override val gameShortName: String override val gameShortName: String

View File

@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.types.ChatMember.abstracts package dev.inmo.tgbotapi.types.ChatMember.abstracts
import dev.inmo.tgbotapi.CommonAbstracts.WithUser
import dev.inmo.tgbotapi.types.ChatMember.* import dev.inmo.tgbotapi.types.ChatMember.*
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.statusField import dev.inmo.tgbotapi.types.statusField
@ -14,9 +15,7 @@ import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
@Serializable(ChatMemberSerializer::class) @Serializable(ChatMemberSerializer::class)
sealed interface ChatMember { sealed interface ChatMember : WithUser
val user: User
}
@RiskFeature @RiskFeature
object ChatMemberSerializer : KSerializer<ChatMember> { object ChatMemberSerializer : KSerializer<ChatMember> {

View File

@ -8,7 +8,7 @@ import kotlinx.serialization.Serializable
data class BaseChosenInlineResult( data class BaseChosenInlineResult(
override val resultId: InlineQueryIdentifier, override val resultId: InlineQueryIdentifier,
@SerialName(fromField) @SerialName(fromField)
override val user: User, override val from: User,
override val inlineMessageId: InlineMessageIdentifier?, override val inlineMessageId: InlineMessageIdentifier?,
override val query: String override val query: String
) : ChosenInlineResult ) : ChosenInlineResult

View File

@ -9,7 +9,7 @@ import kotlinx.serialization.Serializable
data class LocationChosenInlineResult( data class LocationChosenInlineResult(
override val resultId: InlineQueryIdentifier, override val resultId: InlineQueryIdentifier,
@SerialName(fromField) @SerialName(fromField)
override val user: User, override val from: User,
val location: StaticLocation, val location: StaticLocation,
override val inlineMessageId: InlineMessageIdentifier?, override val inlineMessageId: InlineMessageIdentifier?,
override val query: String override val query: String

View File

@ -1,12 +1,11 @@
package dev.inmo.tgbotapi.types.InlineQueries.query package dev.inmo.tgbotapi.types.InlineQueries.query
import dev.inmo.tgbotapi.CommonAbstracts.FromUser
import dev.inmo.tgbotapi.types.InlineQueryIdentifier import dev.inmo.tgbotapi.types.InlineQueryIdentifier
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.chat.ChatType import dev.inmo.tgbotapi.types.chat.ChatType
sealed interface InlineQuery { sealed interface InlineQuery : FromUser {
val id: InlineQueryIdentifier val id: InlineQueryIdentifier
val from: User
val query: String val query: String
val offset: String val offset: String
val chatType: ChatType? val chatType: ChatType?

View File

@ -1,8 +1,9 @@
package dev.inmo.tgbotapi.types.message.ChatEvents package dev.inmo.tgbotapi.types.message.ChatEvents
import dev.inmo.tgbotapi.CommonAbstracts.WithUser
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PublicChatEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PublicChatEvent
data class LeftChatMember( data class LeftChatMember(
val user: User override val user: User
) : PublicChatEvent ) : PublicChatEvent, WithUser

View File

@ -9,7 +9,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.GroupEventMessage
data class CommonGroupEventMessage<T : GroupEvent>( data class CommonGroupEventMessage<T : GroupEvent>(
override val messageId: MessageIdentifier, override val messageId: MessageIdentifier,
override val user: User, override val from: User,
override val chat: GroupChat, override val chat: GroupChat,
override val chatEvent: T, override val chatEvent: T,
override val date: DateTime override val date: DateTime

View File

@ -9,7 +9,7 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
data class CommonMediaGroupMessage<T : MediaGroupContent>( data class CommonMediaGroupMessage<T : MediaGroupContent>(
override val messageId: MessageIdentifier, override val messageId: MessageIdentifier,
override val user: User, override val from: User,
override val chat: Chat, override val chat: Chat,
override val date: DateTime, override val date: DateTime,
override val mediaGroupId: MediaGroupIdentifier, override val mediaGroupId: MediaGroupIdentifier,

View File

@ -9,7 +9,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.SupergroupEventMessage
data class CommonSupergroupEventMessage<T : SupergroupEvent>( data class CommonSupergroupEventMessage<T : SupergroupEvent>(
override val messageId: MessageIdentifier, override val messageId: MessageIdentifier,
override val user: User, override val from: User,
override val chat: SupergroupChat, override val chat: SupergroupChat,
override val chatEvent: T, override val chatEvent: T,
override val date: DateTime override val date: DateTime

View File

@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.types.message package dev.inmo.tgbotapi.types.message
import dev.inmo.tgbotapi.CommonAbstracts.FromUser
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.abstracts.ChannelChat import dev.inmo.tgbotapi.types.chat.abstracts.ChannelChat
import dev.inmo.tgbotapi.types.chat.abstracts.SupergroupChat import dev.inmo.tgbotapi.types.chat.abstracts.SupergroupChat
@ -15,8 +16,8 @@ data class AnonymousForwardInfo(
data class UserForwardInfo( data class UserForwardInfo(
override val dateOfOriginal: TelegramDate, override val dateOfOriginal: TelegramDate,
val from: User override val from: User
) : ForwardInfo() ) : ForwardInfo(), FromUser
data class ForwardFromChannelInfo( data class ForwardFromChannelInfo(
override val dateOfOriginal: TelegramDate, override val dateOfOriginal: TelegramDate,

View File

@ -38,7 +38,7 @@ data class AnonymousGroupContentMessageImpl<T : MessageContent>(
data class CommonGroupContentMessageImpl<T : MessageContent>( data class CommonGroupContentMessageImpl<T : MessageContent>(
override val chat: GroupChat, override val chat: GroupChat,
override val messageId: MessageIdentifier, override val messageId: MessageIdentifier,
override val user: User, override val from: User,
override val date: DateTime, override val date: DateTime,
override val forwardInfo: ForwardInfo?, override val forwardInfo: ForwardInfo?,
override val editDate: DateTime?, override val editDate: DateTime?,

View File

@ -11,7 +11,7 @@ import dev.inmo.tgbotapi.types.passport.PassportData
data class PassportMessage( data class PassportMessage(
override val messageId: MessageIdentifier, override val messageId: MessageIdentifier,
override val chat: Chat, override val chat: Chat,
override val user: User, override val from: User,
override val date: DateTime, override val date: DateTime,
val passportData: PassportData val passportData: PassportData
) : Message, FromUserMessage ) : Message, FromUserMessage

View File

@ -11,7 +11,7 @@ import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
data class PrivateContentMessageImpl<T: MessageContent>( data class PrivateContentMessageImpl<T: MessageContent>(
override val messageId: MessageIdentifier, override val messageId: MessageIdentifier,
override val user: User, override val from: User,
override val chat: Chat, override val chat: Chat,
override val content: T, override val content: T,
override val date: DateTime, override val date: DateTime,

View File

@ -12,7 +12,7 @@ data class PreCheckoutQuery(
@SerialName(idField) @SerialName(idField)
val id: PreCheckoutQueryId, val id: PreCheckoutQueryId,
@SerialName(fromField) @SerialName(fromField)
override val user: User, override val from: User,
@SerialName(currencyField) @SerialName(currencyField)
override val currency: Currency, override val currency: Currency,
@SerialName(totalAmountField) @SerialName(totalAmountField)

View File

@ -10,7 +10,7 @@ data class ShippingQuery(
@SerialName(idField) @SerialName(idField)
val id: ShippingQueryIdentifier, val id: ShippingQueryIdentifier,
@SerialName(fromField) @SerialName(fromField)
override val user: User, override val from: User,
@SerialName(invoicePayloadField) @SerialName(invoicePayloadField)
val invoicePayload: InvoicePayload, val invoicePayload: InvoicePayload,
@SerialName(shippingAddressField) @SerialName(shippingAddressField)

View File

@ -2,8 +2,7 @@ package dev.inmo.tgbotapi.types.polls
import dev.inmo.tgbotapi.CommonAbstracts.FromUser import dev.inmo.tgbotapi.CommonAbstracts.FromUser
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.SerialName import kotlinx.serialization.*
import kotlinx.serialization.Serializable
@Serializable @Serializable
data class PollAnswer( data class PollAnswer(
@ -13,4 +12,8 @@ data class PollAnswer(
override val user: User, override val user: User,
@SerialName(optionIdsField) @SerialName(optionIdsField)
val chosen: List<Int> val chosen: List<Int>
) : FromUser ) : FromUser {
@Transient
override val from: User
get() = user
}

View File

@ -2,8 +2,7 @@
package dev.inmo.tgbotapi.extensions.utils package dev.inmo.tgbotapi.extensions.utils
import dev.inmo.tgbotapi.CommonAbstracts.CommonSendInvoiceData import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.FromUser
import dev.inmo.tgbotapi.requests.send.payments.SendInvoice import dev.inmo.tgbotapi.requests.send.payments.SendInvoice
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.CallbackQuery.* import dev.inmo.tgbotapi.types.CallbackQuery.*
@ -3154,6 +3153,15 @@ inline fun Any.asFromUser(): FromUser? = this as? FromUser
@PreviewFeature @PreviewFeature
inline fun Any.requireFromUser(): FromUser = this as FromUser inline fun Any.requireFromUser(): FromUser = this as FromUser
@PreviewFeature
inline fun <T> Any.whenWithUser(block: (WithUser) -> T) = asWithUser() ?.let(block)
@PreviewFeature
inline fun Any.asWithUser(): WithUser? = this as? WithUser
@PreviewFeature
inline fun Any.requireWithUser(): WithUser = this as WithUser
@PreviewFeature @PreviewFeature
inline fun <T> Any.whenWithOptionalLanguageCode(block: (WithOptionalLanguageCode) -> T) = asWithOptionalLanguageCode() ?.let(block) inline fun <T> Any.whenWithOptionalLanguageCode(block: (WithOptionalLanguageCode) -> T) = asWithOptionalLanguageCode() ?.let(block)

View File

@ -1,5 +1,7 @@
package dev.inmo.tgbotapi.extensions.utils.extensions package dev.inmo.tgbotapi.extensions.utils.extensions
import dev.inmo.tgbotapi.CommonAbstracts.FromUser
import dev.inmo.tgbotapi.CommonAbstracts.WithUser
import dev.inmo.tgbotapi.extensions.utils.asFromUser import dev.inmo.tgbotapi.extensions.utils.asFromUser
import dev.inmo.tgbotapi.extensions.utils.asUser import dev.inmo.tgbotapi.extensions.utils.asUser
import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat
@ -12,20 +14,24 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.PreviewFeature import dev.inmo.tgbotapi.utils.PreviewFeature
@PreviewFeature @PreviewFeature
fun Update.sourceChat(): Chat? = when (this) { fun Update.sourceChat(): Chat? = when {
is MediaGroupUpdate -> when (this) { this is MediaGroupUpdate -> when (this) {
is SentMediaGroupUpdate -> data.chat is SentMediaGroupUpdate -> data.chat
is EditMediaGroupUpdate -> data.chat is EditMediaGroupUpdate -> data.chat
} }
is BaseMessageUpdate -> data.chat this is BaseMessageUpdate -> data.chat
is InlineQueryUpdate -> data.from else -> {
is ChosenInlineResultUpdate -> data.user when (val data = data) {
is CallbackQueryUpdate -> data.user is FromUser -> data.from
is PreCheckoutQueryUpdate -> data.user is WithUser -> data.user
is PollAnswerUpdate -> data.user else -> null
is ShippingQueryUpdate -> data.user }
else -> null }
} }
@PreviewFeature @PreviewFeature
fun Update.sourceUser(): User? = data.asFromUser()?.user ?: sourceChat()?.asUser() fun Update.sourceUser(): User? = when (val data = data) {
is FromUser -> data.from
is WithUser -> data.user
else -> sourceChat()?.asUser()
}