From 0eba0c4e15119004ccad9d9432a6bf4602ad95df Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 16 Mar 2023 19:29:35 +0600 Subject: [PATCH] improvements in same-notations --- CHANGELOG.md | 3 + .../dev/inmo/tgbotapi/abstracts/WithChat.kt | 10 ++ .../types/message/abstracts/Message.kt | 4 +- .../extensions/utils/extensions/FlowsSame.kt | 37 +++++ .../extensions/utils/extensions/Same.kt | 131 ++++++++++++++---- 5 files changed, 155 insertions(+), 30 deletions(-) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/abstracts/WithChat.kt create mode 100644 tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/FlowsSame.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 6819de7a25..37419f2717 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 7.0.1 +* `Utils`: + * Improvements in `same`-notations + ## 7.0.0 This update contains support of [Telegram Bot API 6.6](https://core.telegram.org/bots/api-changelog#march-9-2023) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/abstracts/WithChat.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/abstracts/WithChat.kt new file mode 100644 index 0000000000..1cdba4b9f3 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/abstracts/WithChat.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.abstracts + +import dev.inmo.tgbotapi.types.chat.Chat + +/** + * All inheritors of this interface have [chat] field and related to this [chat] + */ +interface WithChat { + val chat: Chat +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt index e9593c2da4..49f9eda9b9 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.types.message.abstracts import com.soywiz.klock.DateTime +import dev.inmo.tgbotapi.abstracts.WithChat import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.chat.Chat @@ -11,9 +12,8 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder @ClassCastsIncluded -interface Message { +interface Message : WithChat { val messageId: MessageId - val chat: Chat val date: DateTime } diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/FlowsSame.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/FlowsSame.kt new file mode 100644 index 0000000000..a45ecd1cb5 --- /dev/null +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/FlowsSame.kt @@ -0,0 +1,37 @@ +package dev.inmo.tgbotapi.extensions.utils.extensions + +import dev.inmo.tgbotapi.abstracts.FromUser +import dev.inmo.tgbotapi.abstracts.WithChat +import dev.inmo.tgbotapi.types.ChatIdentifier +import dev.inmo.tgbotapi.types.UserId +import dev.inmo.tgbotapi.types.chat.Chat +import dev.inmo.tgbotapi.types.chat.User +import dev.inmo.tgbotapi.types.message.abstracts.Message +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.transform + +/** + * Will pass only those [T] which have [sameChat] as [chatId] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Flow.fromChat(chatId: ChatIdentifier): Flow = filter { it.sameChat(chatId) } + +/** + * Will pass only those [T] which have [sameChat] as [chatId] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Flow.fromChat(chat: Chat): Flow = fromChat(chat.id) + +/** + * @return [Flow] with the [FromUser.user] field [User.id] the same as [userId] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Flow.fromUser(userId: UserId): Flow = filter { it.user.id == userId } + +/** + * @return [Flow] with the [FromUser.user] field [User.id] the same as [user] [User.id] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Flow.fromUser(user: User): Flow = fromUser(user.id) + diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/Same.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/Same.kt index 441c59e101..8ef2b69166 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/Same.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/Same.kt @@ -1,24 +1,120 @@ package dev.inmo.tgbotapi.extensions.utils.extensions -import dev.inmo.tgbotapi.abstracts.FromUser -import dev.inmo.tgbotapi.types.IdChatIdentifier +import dev.inmo.tgbotapi.abstracts.WithChat +import dev.inmo.tgbotapi.extensions.utils.usernameChatOrNull +import dev.inmo.tgbotapi.extensions.utils.whenUsernameChat +import dev.inmo.tgbotapi.types.ChatIdentifier +import dev.inmo.tgbotapi.types.MessageId +import dev.inmo.tgbotapi.types.MessageThreadId +import dev.inmo.tgbotapi.types.Username +import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.message.abstracts.Message +import dev.inmo.tgbotapi.types.threadId import dev.inmo.tgbotapi.utils.extensions.threadIdOrNull -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.transform + +/** + * @return true in case if [this] message is placed in the chat with id == [chatId] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun WithChat.sameChat(chatId: ChatIdentifier) = chat.id == chatId || (chatId is Username && chat.whenUsernameChat { + it.username == chatId +} ?: false) + +/** + * @return true in case if [this] message is placed in the [chat] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun WithChat.sameChat(chat: Chat) = sameChat(chat.id) || chat.usernameChatOrNull() ?.username ?.let { sameChat(it) } ?: false /** * @return true in case if [this] message is placed in the same chat that [other] */ @Suppress("NOTHING_TO_INLINE") -inline fun Message.sameChat(other: Message) = chat.id == other.chat.id +inline fun WithChat.sameChat(other: Message) = sameChat(other.chat) + +/** + * @return true in case if [this] message is from the same chat (with id == [chatId]) and [this] [Message.messageId] + * equal [messageId] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameMessage( + chatId: ChatIdentifier, + messageId: MessageId +) = sameChat(chatId) && this.messageId == messageId + +/** + * @return true in case if [this] message is from the same [chat] and [this] [Message.messageId] equal [messageId] + * identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameMessage( + chat: Chat, + messageId: MessageId +) = sameChat(chat) && this.messageId == messageId /** * @return true in case if [this] message is the same as [other]. The same here means that these messages from one chat * and have equal [Message.messageId] identifier */ @Suppress("NOTHING_TO_INLINE") -inline fun Message.sameMessage(other: Message) = sameChat(other) && messageId == other.messageId +inline fun Message.sameMessage(other: Message) = sameMessage(other.chat, other.messageId) + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is in the chat [chatId] and topic [threadId]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameTopic( + chatId: ChatIdentifier, + threadId: MessageThreadId? = chatId.threadId +) = sameChat(chatId) && threadIdOrNull == threadId + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is in the chat [chatId] and topic [threadId]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameThread( + chatId: ChatIdentifier, + threadId: MessageThreadId? = chatId.threadId +) = sameTopic(chatId, threadId) + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is from the [chat] and topic [threadId]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameTopic( + chat: Chat, + threadId: MessageThreadId? = chat.id.threadId +) = sameTopic(chat.id, threadId) + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is from the [chat] and topic [threadId]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameThread( + chat: Chat, + threadId: MessageThreadId? = chat.id.threadId +) = sameThread(chat.id, threadId) + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is from the same chat and topic as [other]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameTopic(other: Message) = sameTopic(other.chat, other.threadIdOrNull) /** * Thread is the same thing that topic @@ -27,25 +123,4 @@ inline fun Message.sameMessage(other: Message) = sameChat(other) && messageId == * from one chat and have equal [Message.threadIdOrNull] identifier */ @Suppress("NOTHING_TO_INLINE") -inline fun Message.sameTopic(other: Message) = sameChat(other) && threadIdOrNull == other.threadIdOrNull - -/** - * Thread is the same thing that topic - * - * @return true in case if [this] message is in the same topic as the [other]. The same here means that these messages - * from one chat and have equal [Message.threadIdOrNull] identifier - */ -@Suppress("NOTHING_TO_INLINE") -inline fun Message.sameThread(other: Message) = sameChat(other) && threadIdOrNull == other.threadIdOrNull - -@Suppress("NOTHING_TO_INLINE") -inline fun Flow.filterSameChat(chatId: IdChatIdentifier): Flow = - transform { value -> - if (value.chat.id.chatId == chatId.chatId) return@transform emit(value) - } - -@Suppress("NOTHING_TO_INLINE") -inline fun Flow.filterSameUser(userId: IdChatIdentifier): Flow = - transform { value -> - if (value.from.id.chatId == userId.chatId) return@transform emit(value) - } +inline fun Message.sameThread(other: Message) = sameTopic(other)