From 8930a661345753616e55dc50a43f348e3710d7ed Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 23 Mar 2022 11:48:20 +0600 Subject: [PATCH] with*Action block called once --- CHANGELOG.md | 3 + .../extensions/api/send/SendActionDSL.kt | 211 +++++++++++++++--- 2 files changed, 183 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81858abcd6..7814064877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.38.10 +* `API`: + * All `with*Action` extensions got a contracts which declare that `block` will be called once + ## 0.38.9 * `Core`: diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt index c247ad55c1..e9d5a18ebf 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt @@ -8,15 +8,20 @@ import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.actions.* import dev.inmo.tgbotapi.types.chat.abstracts.Chat import kotlinx.coroutines.* +import kotlin.contracts.* import kotlin.coroutines.coroutineContext private const val refreshTime: MilliSeconds = (botActionActualityTime - 1) * 1000L typealias TelegramBotActionCallback = suspend TelegramBot.() -> T +@OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withAction( actionRequest: SendAction, block: TelegramBotActionCallback ): T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } val botActionJob = CoroutineScope(coroutineContext).launch { while (isActive) { delay(refreshTime) @@ -30,46 +35,190 @@ suspend fun TelegramBot.withAction( return result.getOrThrow() } +@OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withAction( chatId: ChatId, action: BotAction, block: TelegramBotActionCallback -) = withAction( - SendAction(chatId, action), - block -) +): T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction( + SendAction(chatId, action), + block + ) +} +@OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withAction( chat: Chat, action: BotAction, block: TelegramBotActionCallback -) = withAction( - chat.id, - action, - block -) +): T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction( + chat.id, + action, + block + ) +} -suspend fun TelegramBot.withTypingAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, TypingAction, block) -suspend fun TelegramBot.withUploadPhotoAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, UploadPhotoAction, block) -suspend fun TelegramBot.withRecordVideoAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, RecordVideoAction, block) -suspend fun TelegramBot.withUploadVideoAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, UploadVideoAction, block) -suspend fun TelegramBot.withRecordVoiceAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, RecordVoiceAction, block) -suspend fun TelegramBot.withUploadVoiceAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, UploadVoiceAction, block) -suspend fun TelegramBot.withUploadDocumentAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, UploadDocumentAction, block) -suspend fun TelegramBot.withFindLocationAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, FindLocationAction, block) -suspend fun TelegramBot.withRecordVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, RecordVideoNoteAction, block) -suspend fun TelegramBot.withUploadVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, UploadVideoNoteAction, block) -suspend fun TelegramBot.withChooseStickerAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, ChooseStickerAction, block) +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withTypingAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, TypingAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadPhotoAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, UploadPhotoAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withRecordVideoAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, RecordVideoAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadVideoAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, UploadVideoAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withRecordVoiceAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, RecordVoiceAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadVoiceAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, UploadVoiceAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadDocumentAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, UploadDocumentAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withFindLocationAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, FindLocationAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withRecordVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, RecordVideoNoteAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, UploadVideoNoteAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withChooseStickerAction(chatId: ChatId, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chatId, ChooseStickerAction, block) +} -suspend fun TelegramBot.withTypingAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, TypingAction, block) -suspend fun TelegramBot.withUploadPhotoAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, UploadPhotoAction, block) -suspend fun TelegramBot.withRecordVideoAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, RecordVideoAction, block) -suspend fun TelegramBot.withUploadVideoAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, UploadVideoAction, block) -suspend fun TelegramBot.withRecordVoiceAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, RecordVoiceAction, block) -suspend fun TelegramBot.withUploadVoiceAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, UploadVoiceAction, block) -suspend fun TelegramBot.withUploadDocumentAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, UploadDocumentAction, block) -suspend fun TelegramBot.withFindLocationAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, FindLocationAction, block) -suspend fun TelegramBot.withRecordVideoNoteAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, RecordVideoNoteAction, block) -suspend fun TelegramBot.withUploadVideoNoteAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, UploadVideoNoteAction, block) -suspend fun TelegramBot.withChooseStickerAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, ChooseStickerAction, block) +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withTypingAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, TypingAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadPhotoAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, UploadPhotoAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withRecordVideoAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, RecordVideoAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadVideoAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, UploadVideoAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withRecordVoiceAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, RecordVoiceAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadVoiceAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, UploadVoiceAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadDocumentAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, UploadDocumentAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withFindLocationAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, FindLocationAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withRecordVideoNoteAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, RecordVideoNoteAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withUploadVideoNoteAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, UploadVideoNoteAction, block) +} +@OptIn(ExperimentalContracts::class) +suspend fun TelegramBot.withChooseStickerAction(chat: Chat, block: TelegramBotActionCallback) : T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withAction(chat, ChooseStickerAction, block) +}