From 24310df9b305b077ae540701445a90c40c8ad4cb Mon Sep 17 00:00:00 2001 From: Henriquelay <37563861+Henriquelay@users.noreply.github.com> Date: Tue, 6 Feb 2024 01:25:41 -0300 Subject: [PATCH] Implement `GetChatId` for `teloxide-core::types::*` --- CHANGELOG.md | 1 + .../src/dispatching/dialogue/get_chat_id.rs | 105 ++++++++++++++++-- 2 files changed, 98 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f458549..b72fa104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `filter_video_chat_ended` - `filter_video_chat_participants_invited` - `filter_web_app_data` +- Implement `GetChatId` for `teloxide_core::types::{BotCommandScope, Chat, ChatJoinRequest, ChatMemberUpdated, MessageCommon, Recipient, ResponseParameters, TargetMessage, UpdateKind}`. ### Fixed diff --git a/crates/teloxide/src/dispatching/dialogue/get_chat_id.rs b/crates/teloxide/src/dispatching/dialogue/get_chat_id.rs index a0e72f8b..c80bd76a 100644 --- a/crates/teloxide/src/dispatching/dialogue/get_chat_id.rs +++ b/crates/teloxide/src/dispatching/dialogue/get_chat_id.rs @@ -1,25 +1,114 @@ -use crate::types::{CallbackQuery, ChatId, Message, Update}; +use crate::types::{ + BotCommandScope, CallbackQuery, Chat, ChatId, ChatJoinRequest, ChatMemberUpdated, Message, + MessageCommon, Recipient, ResponseParameters, TargetMessage, Update, UpdateKind, +}; -/// Something that may has a chat ID. +/// Something that may have a chat ID. pub trait GetChatId { #[must_use] fn chat_id(&self) -> Option; } -impl GetChatId for Message { - fn chat_id(&self) -> Option { - Some(self.chat.id) - } -} - impl GetChatId for CallbackQuery { fn chat_id(&self) -> Option { self.message.as_ref().map(|mes| mes.chat.id) } } +impl GetChatId for MessageCommon { + fn chat_id(&self) -> Option { + self.sender_chat.as_ref().map(|chat| chat.id) + } +} + impl GetChatId for Update { fn chat_id(&self) -> Option { self.chat().map(|chat| chat.id) } } + +impl GetChatId for Recipient { + fn chat_id(&self) -> Option { + match self { + Recipient::Id(chat_id) => Some(*chat_id), + Recipient::ChannelUsername(_) => None, + } + } +} + +impl GetChatId for BotCommandScope { + fn chat_id(&self) -> Option { + match self { + BotCommandScope::Default + | BotCommandScope::AllPrivateChats + | BotCommandScope::AllGroupChats + | BotCommandScope::AllChatAdministrators => None, + BotCommandScope::Chat { chat_id: recipient } + | BotCommandScope::ChatAdministrators { chat_id: recipient } + | BotCommandScope::ChatMember { chat_id: recipient, .. } => recipient.chat_id(), + } + } +} + +impl GetChatId for Chat { + fn chat_id(&self) -> Option { + Some(self.id) + } +} + +impl GetChatId for UpdateKind { + fn chat_id(&self) -> Option { + match self { + UpdateKind::Message(message) + | UpdateKind::EditedMessage(message) + | UpdateKind::ChannelPost(message) + | UpdateKind::EditedChannelPost(message) => GetChatId::chat_id(message), + UpdateKind::CallbackQuery(callback_query) => callback_query.chat_id(), + UpdateKind::MyChatMember(chat_member_updated) => chat_member_updated.chat_id(), + UpdateKind::ChatMember(chat_member_updated) => chat_member_updated.chat_id(), + UpdateKind::ChatJoinRequest(chat_join_request) => chat_join_request.chat_id(), + UpdateKind::InlineQuery(_) + | UpdateKind::ChosenInlineResult(_) + | UpdateKind::ShippingQuery(_) + | UpdateKind::PreCheckoutQuery(_) + | UpdateKind::Poll(_) + | UpdateKind::PollAnswer(_) + | UpdateKind::Error(_) => None, + } + } +} + +impl GetChatId for ResponseParameters { + fn chat_id(&self) -> Option { + match self { + ResponseParameters::MigrateToChatId(chat_id) => Some(*chat_id), + ResponseParameters::RetryAfter(_) => None, + } + } +} + +impl GetChatId for TargetMessage { + fn chat_id(&self) -> Option { + match self { + TargetMessage::Common { chat_id: recipient, .. } => recipient.chat_id(), + TargetMessage::Inline { .. } => None, + } + } +} + +/// Implements [`GetChatId`] for all types passed in, as long as they have a +/// `chat` field with a `Chat` type +macro_rules! impl_GetChatId_for_chat_field { + // Comma-separated list of types bound to `t` + ($($t:ty),* $(,)?) => { + $( + impl GetChatId for $t { + fn chat_id(&self) -> Option { + Some(self.chat.id) + } + } + )* + }; +} + +impl_GetChatId_for_chat_field!(Message, ChatMemberUpdated, ChatJoinRequest);