1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-12-22 00:27:14 +00:00

Merge branch 'master' into 22.0.0

This commit is contained in:
InsanusMokrassar 2024-12-05 08:30:36 +06:00
commit bc00e1f28a
27 changed files with 107 additions and 70 deletions

View File

@ -2,6 +2,18 @@
## 22.0.0
## 21.0.1
* `Core`:
* Improvements in `Update.sourceUser` extension
* Add extension `PrivateChat.toUser`
* Builder methods of `TextSource`s (like `pre` which returns `PreTextSource`) lost suppression of `redundant inline`
due to its redundancy
* Add `mention` builders for `EntitiesBuilder` with `UserId` as variant instead of `User`
* `BehaviourBuilder`:
* Add support of several rounds for `CombinedSubcontextInitialAction`. Now it will try hard to execute all its
`SubAction` while all actions will not be completed successfully OR all left actions will not complete with errors
## 21.0.0
* `Version`:

View File

@ -6,6 +6,13 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
/**
* Contains [SubAction]s which will be used in [subcontextInitialAction] in order they has been passed in [subactions].
*
* Its [subcontextInitialAction] will iterate over incoming [subactions] until all will be completed successfully OR
* none will be successful during round of running:
*
* * Run all
* * Exclude from current running successful items
* * Do again if there are some items to run
*/
class CombinedSubcontextInitialAction(
val subactions: List<SubAction>,
@ -25,14 +32,30 @@ class CombinedSubcontextInitialAction(
}
}
val subcontextInitialAction: CustomBehaviourContextAndTypeReceiver<BehaviourContext, Unit, Update> = { update ->
subactions.forEach { subaction ->
with(subaction) {
runCatching {
invoke(update)
}.onFailure {
logger.error("Unable to execute $subaction for update $update", it)
val leftSubActions = subactions.toMutableSet()
val successSubActions = mutableSetOf<SubAction>()
while (leftSubActions.isNotEmpty()) {
leftSubActions.forEach { subaction ->
with(subaction) {
runCatching {
invoke(update)
}.onFailure {
logger.error(it) {
"Unable to execute $subaction for update $update. Will try on next round"
}
}.onSuccess {
successSubActions.add(subaction)
}
}
}
leftSubActions.removeAll(successSubActions)
if (successSubActions.isEmpty()) {
logger.error {
"Some SubActions have been unable to complete successfully:${leftSubActions.joinToString("\n") { it.toString() }}"
}
break
}
successSubActions.clear()
}
}
}

View File

@ -26989,6 +26989,9 @@ public final class dev/inmo/tgbotapi/utils/EntitiesBuilderKt {
public static final fun mention (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/util/List;Ldev/inmo/tgbotapi/types/chat/User;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mention (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Lkotlin/jvm/functions/Function1;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mention (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;[Ldev/inmo/tgbotapi/types/message/textsources/TextSource;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mention-dEpx-Zg (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;J[Ldev/inmo/tgbotapi/types/message/textsources/TextSource;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mention-rcVkPyE (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/lang/String;J)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mention-rcVkPyE (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/util/List;J)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mentionln (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ldev/inmo/tgbotapi/types/chat/User;[Ldev/inmo/tgbotapi/types/message/textsources/TextSource;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mentionln (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/lang/String;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mentionln (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/lang/String;Ldev/inmo/tgbotapi/types/chat/User;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
@ -26996,6 +26999,9 @@ public final class dev/inmo/tgbotapi/utils/EntitiesBuilderKt {
public static final fun mentionln (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/util/List;Ldev/inmo/tgbotapi/types/chat/User;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mentionln (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Lkotlin/jvm/functions/Function1;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mentionln (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;[Ldev/inmo/tgbotapi/types/message/textsources/TextSource;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mentionln-dEpx-Zg (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;J[Ldev/inmo/tgbotapi/types/message/textsources/TextSource;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mentionln-rcVkPyE (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/lang/String;J)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun mentionln-rcVkPyE (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/util/List;J)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun phone (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/lang/String;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun phone (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Ljava/util/List;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
public static final fun phone (Ldev/inmo/tgbotapi/utils/EntitiesBuilder;Lkotlin/jvm/functions/Function1;)Ldev/inmo/tgbotapi/utils/EntitiesBuilder;
@ -27121,6 +27127,10 @@ public final class dev/inmo/tgbotapi/utils/MimeTypeSerializer : kotlinx/serializ
public abstract interface annotation class dev/inmo/tgbotapi/utils/PreviewFeature : java/lang/annotation/Annotation {
}
public final class dev/inmo/tgbotapi/utils/PrivateChatToUserKt {
public static final fun toUser (Ldev/inmo/tgbotapi/types/chat/PrivateChat;)Ldev/inmo/tgbotapi/types/chat/User;
}
public final class dev/inmo/tgbotapi/utils/RGBColor {
public static final field Companion Ldev/inmo/tgbotapi/utils/RGBColor$Companion;
public static final synthetic fun box-impl (I)Ldev/inmo/tgbotapi/utils/RGBColor;

View File

@ -18,9 +18,6 @@ data class BlockquoteTextSource @RiskFeature(DirectInvocationOfTextSourceConstru
override val html: String by lazy { blockquoteHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun blockquote(parts: TextSourcesList) = BlockquoteTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun blockquote(vararg parts: TextSource) = blockquote(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun blockquote(text: String) = blockquote(regular(text))

View File

@ -18,9 +18,6 @@ data class BoldTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor)
override val html: String by lazy { boldHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun bold(parts: TextSourcesList) = BoldTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun bold(vararg parts: TextSource) = bold(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun bold(text: String) = bold(regular(text))

View File

@ -33,8 +33,6 @@ data class BotCommandTextSource @RiskFeature(DirectInvocationOfTextSourceConstru
/**
* @param command Without leading "/"
*/
@Suppress("NOTHING_TO_INLINE")
inline fun botCommand(command: String) = BotCommandTextSource("/$command")
@Suppress("NOTHING_TO_INLINE")
inline fun botCommand(botCommand: BotCommand) = botCommand(botCommand.command)

View File

@ -25,9 +25,6 @@ data class CashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructo
override val html: String by lazy { cashTagHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun cashTag(parts: TextSourcesList) = CashTagTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun cashTag(vararg parts: TextSource) = cashTag(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun cashTag(tag: String) = cashTag(regular(tag))

View File

@ -16,5 +16,4 @@ data class CodeTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor)
override val html: String by lazy { source.codeHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun code(code: String) = CodeTextSource(code)

View File

@ -20,12 +20,10 @@ data class CustomEmojiTextSource @RiskFeature(DirectInvocationOfTextSourceConstr
override val html: String by lazy { source.customEmojiHTML(customEmojiId) }
}
@Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_API_USAGE")
@Suppress("EXPERIMENTAL_API_USAGE")
inline fun customEmoji(emojiId: CustomEmojiId, parts: TextSourcesList) = CustomEmojiTextSource(parts.makeString(), emojiId, parts)
@Suppress("NOTHING_TO_INLINE")
inline fun customEmoji(emojiId: CustomEmojiId, vararg parts: TextSource) = customEmoji(emojiId, parts.toList())
/**
* Without sharp (#)
*/
@Suppress("NOTHING_TO_INLINE")
inline fun customEmoji(emojiId: CustomEmojiId, text: String) = customEmoji(emojiId, regular(text))

View File

@ -18,9 +18,6 @@ data class EMailTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor)
override val html: String by lazy { emailHTML(source) }
}
@Suppress("NOTHING_TO_INLINE")
inline fun email(parts: TextSourcesList) = EMailTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun email(vararg parts: TextSource) = email(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun email(emailAddress: String) = email(regular(emailAddress))

View File

@ -18,9 +18,6 @@ data class ExpandableBlockquoteTextSource @RiskFeature(DirectInvocationOfTextSou
override val html: String by lazy { expandableBlockquoteHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun expandableBlockquote(parts: TextSourcesList) = ExpandableBlockquoteTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun expandableBlockquote(vararg parts: TextSource) = expandableBlockquote(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun expandableBlockquote(text: String) = expandableBlockquote(regular(text))

View File

@ -32,12 +32,10 @@ data class HashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructo
}
}
@Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_API_USAGE")
@Suppress("EXPERIMENTAL_API_USAGE")
inline fun hashtag(parts: TextSourcesList) = (regular("#") + parts).let { HashTagTextSource(it.makeString(), it) }
@Suppress("NOTHING_TO_INLINE")
inline fun hashtag(vararg parts: TextSource) = hashtag(parts.toList())
/**
* Without sharp (#)
*/
@Suppress("NOTHING_TO_INLINE")
inline fun hashtag(hashtag: String) = hashtag(regular(hashtag))

View File

@ -18,10 +18,7 @@ data class ItalicTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor
override val html: String by lazy { italicHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun italic(parts: TextSourcesList) = ItalicTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun italic(vararg parts: TextSource) = italic(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun italic(text: String) = italic(regular(text))

View File

@ -33,17 +33,13 @@ data class MentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructo
}
}
@Suppress("NOTHING_TO_INLINE")
inline fun mention(parts: TextSourcesList) = (regular("@") + parts).let { MentionTextSource(it.makeString(), it) }
@Suppress("NOTHING_TO_INLINE")
inline fun mention(vararg parts: TextSource) = mention(parts.toList())
/**
* Without leading "@"
*/
@Suppress("NOTHING_TO_INLINE")
inline fun mention(whoToMention: String) = mention(regular(whoToMention))
@Suppress("NOTHING_TO_INLINE")
inline fun mention(whoToMention: Username) = mention(whoToMention.full.dropWhile { it == '@' })

View File

@ -18,10 +18,7 @@ data class PhoneNumberTextSource @RiskFeature(DirectInvocationOfTextSourceConstr
override val html: String by lazy { phoneHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun phone(parts: TextSourcesList) = PhoneNumberTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun phone(vararg parts: TextSource) = phone(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun phone(number: String) = phone(regular(number))

View File

@ -17,6 +17,5 @@ data class PreTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) c
override val html: String by lazy { source.preHTML(language) }
}
@Suppress("NOTHING_TO_INLINE")
inline fun pre(code: String, language: String? = null) = PreTextSource(code, language)

View File

@ -16,8 +16,6 @@ data class RegularTextSource @RiskFeature(DirectInvocationOfTextSourceConstructo
override val html: String by lazy { source.regularHtml() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun regular(text: String) = RegularTextSource(text)
@Suppress("NOTHING_TO_INLINE")
inline fun regularln(text: String) = regular("$text\n")

View File

@ -18,10 +18,7 @@ data class SpoilerTextSource @RiskFeature(DirectInvocationOfTextSourceConstructo
override val html: String by lazy { spoilerHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun spoiler(parts: TextSourcesList) = SpoilerTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun spoiler(vararg parts: TextSource) = spoiler(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun spoiler(text: String) = spoiler(regular(text))

View File

@ -18,9 +18,6 @@ data class StrikethroughTextSource @RiskFeature(DirectInvocationOfTextSourceCons
override val markdown: String by lazy { source.strikethroughMarkdown() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun strikethrough(parts: TextSourcesList) = StrikethroughTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun strikethrough(vararg parts: TextSource) = strikethrough(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun strikethrough(text: String) = strikethrough(regular(text))

View File

@ -17,5 +17,4 @@ data class TextLinkTextSource @RiskFeature(DirectInvocationOfTextSourceConstruct
override val html: String by lazy { source.linkHTML(url) }
}
@Suppress("NOTHING_TO_INLINE")
inline fun link(text: String, url: String) = TextLinkTextSource(text, url)

View File

@ -22,34 +22,21 @@ data class TextMentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstr
override val html: String by lazy { textMentionHTML(user.id) }
}
@Suppress("NOTHING_TO_INLINE")
inline fun mention(parts: TextSourcesList, user: User) = TextMentionTextSource(parts.makeString(), user, parts)
@Suppress("NOTHING_TO_INLINE")
inline fun User.mention(parts: TextSourcesList) = mention(parts, this)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(parts: TextSourcesList, userId: UserId) = mention(parts, CommonUser(userId, ""))
@Suppress("NOTHING_TO_INLINE")
inline fun UserId.mention(parts: TextSourcesList) = mention(parts, this)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(parts: TextSourcesList, id: RawChatId) = mention(parts, UserId(id))
@Suppress("NOTHING_TO_INLINE")
inline fun RawChatId.mention(parts: TextSourcesList) = mention(parts, this)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(user: User, vararg parts: TextSource) = mention(
textSourcesOrElseTextSource(parts.toList()) {
RegularTextSource("${user.lastName} ${user.firstName}")
},
user
)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(text: String, user: User) = mention(user, regular(text))
@Suppress("NOTHING_TO_INLINE")
inline fun User.mention(text: String) = mention(this, regular(text))
@Suppress("NOTHING_TO_INLINE")
inline fun mention(text: String, userId: UserId) = mention(text, CommonUser(userId, ""))
@Suppress("NOTHING_TO_INLINE")
inline fun UserId.mention(text: String) = mention(text, this)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(text: String, id: RawChatId) = mention(text, UserId(id))
@Suppress("NOTHING_TO_INLINE")
inline fun RawChatId.mention(text: String) = mention(text, this)

View File

@ -101,7 +101,6 @@ fun List<TextSource>.splitForCaption(): List<List<TextSource>> {
/**
* This method will prepare [TextSource]s list for messages with [textLength]
*/
@Suppress("NOTHING_TO_INLINE")
inline fun List<TextSource>.splitForText(): List<List<TextSource>> = splitForMessage(textLength)
fun List<TextSource>.separateForMessage(limit: IntRange, numberOfParts: Int? = null): List<List<TextSource>> = splitForMessage(limit, numberOfParts)
@ -115,5 +114,4 @@ fun List<TextSource>.separateForCaption(): List<List<TextSource>> = splitForCapt
/**
* This method will prepare [TextSource]s list for messages with [textLength]
*/
@Suppress("NOTHING_TO_INLINE")
inline fun List<TextSource>.separateForText(): List<List<TextSource>> = splitForText()

View File

@ -16,5 +16,4 @@ data class URLTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) c
override val html: String by lazy { source.linkHTML(source) }
}
@Suppress("NOTHING_TO_INLINE")
inline fun link(url: String) = URLTextSource(url)

View File

@ -18,9 +18,6 @@ data class UnderlineTextSource @RiskFeature(DirectInvocationOfTextSourceConstruc
override val html: String by lazy { underlineHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun underline(parts: TextSourcesList) = UnderlineTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun underline(vararg parts: TextSource) = underline(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun underline(text: String) = underline(regular(text))

View File

@ -5,6 +5,7 @@ package dev.inmo.tgbotapi.utils
import dev.inmo.micro_utils.common.joinTo
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.CustomEmojiId
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.message.textsources.*
@ -458,6 +459,31 @@ inline fun EntitiesBuilder.mention(text: String, user: User) = add(dev.inmo.tgbo
*/
inline fun EntitiesBuilder.mentionln(text: String, user: User) = mention(text, user) + newLine
/**
* Add mention using [EntitiesBuilder.add] with [dev.inmo.tgbotapi.types.message.textsources.mention]
*/
inline fun EntitiesBuilder.mention(parts: TextSourcesList, userId: UserId) = add(dev.inmo.tgbotapi.types.message.textsources.mention(parts, userId))
/**
* Version of [EntitiesBuilder.mention] with new line at the end
*/
inline fun EntitiesBuilder.mentionln(parts: TextSourcesList, userId: UserId) = mention(parts, userId) + newLine
inline fun EntitiesBuilder.mention(
userId: UserId,
vararg parts: TextSource
) = mention(parts.toList(), userId)
/**
* Version of [EntitiesBuilder.mention] with new line at the end
*/
inline fun EntitiesBuilder.mentionln(userId: UserId, vararg parts: TextSource) = mention(userId, *parts) + newLine
/**
* Add mention using [EntitiesBuilder.add] with [dev.inmo.tgbotapi.types.message.textsources.mention]
*/
inline fun EntitiesBuilder.mention(text: String, userId: UserId) = add(dev.inmo.tgbotapi.types.message.textsources.mention(text, userId))
/**
* Version of [EntitiesBuilder.mention] with new line at the end
*/
inline fun EntitiesBuilder.mentionln(text: String, userId: UserId) = mention(text, userId) + newLine
/**
* Add phone using [EntitiesBuilder.add] with [dev.inmo.tgbotapi.types.message.textsources.phone]

View File

@ -0,0 +1,21 @@
package dev.inmo.tgbotapi.utils
import dev.inmo.tgbotapi.types.chat.*
/**
* Trying to convert current [PrivateChat] to [User]
*
* * If [this] actually is [User] or some [Bot], will return this as is
* * If [this] is some [PreviewPrivateChat], will create new [CommonUser]
*
* !!!WARNING!!! The returned [User] CAN BE NOT EQUAL to user from some
* [dev.inmo.tgbotapi.types.message.abstracts.ContentMessage] due to absence of some fields (like premium flag or
* language)
*/
fun PrivateChat.toUser(): User = when (this) {
is ExtendedPrivateChatImpl -> CommonUser(id, firstName, lastName, username)
is CommonUser -> this
is CommonBot -> this
is PrivateChatImpl -> CommonUser(id, firstName, lastName, username)
is ExtendedBot -> this
}

View File

@ -9,12 +9,14 @@ import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.LocationChosenIn
import dev.inmo.tgbotapi.types.InlineQueries.query.BaseInlineQuery
import dev.inmo.tgbotapi.types.InlineQueries.query.LocationInlineQuery
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.PrivateChat
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.queries.callback.*
import dev.inmo.tgbotapi.types.update.*
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.PreviewFeature
import dev.inmo.tgbotapi.utils.toUser
fun CallbackQuery.sourceChat() = when (this) {
is InlineMessageIdDataCallbackQuery -> null
@ -86,9 +88,13 @@ fun Update.sourceChatWithConverters(
@PreviewFeature
fun Update.sourceChat(): Chat? = sourceChatWithConverters()
/**
* Trying to get the user from [Update]. In some cases it can be the user without actual fields like
* [dev.inmo.tgbotapi.types.chat.CommonUser.isPremium] due to in these cases will be used [toUser] cast
*/
@PreviewFeature
fun Update.sourceUser(): User? = when (val data = data) {
is FromUser -> data.from
is WithUser -> data.user
else -> sourceChat()?.asUser()
else -> sourceChat() ?.asUser() ?: ((sourceChat() as? PrivateChat) ?.toUser())
}