Skip to main content

rustigram_api/methods/
forum.rs

1use crate::client::BotClient;
2use crate::error::Result;
3use rustigram_types::forum::ForumTopic;
4use rustigram_types::user::ChatId;
5use serde::Serialize;
6use std::future::{Future, IntoFuture};
7use std::pin::Pin;
8
9// ─── createForumTopic ─────────────────────────────────────────────────────────
10
11#[derive(Serialize)]
12struct CreateForumTopicParams {
13    chat_id: ChatId,
14    name: String,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    icon_color: Option<u32>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    icon_custom_emoji_id: Option<String>,
19}
20
21/// Builder for the [`createForumTopic`](https://core.telegram.org/bots/api#createforumtopic) method.
22pub struct CreateForumTopic {
23    client: BotClient,
24    params: CreateForumTopicParams,
25}
26
27impl CreateForumTopic {
28    pub(crate) fn new(
29        client: BotClient,
30        chat_id: impl Into<ChatId>,
31        name: impl Into<String>,
32    ) -> Self {
33        Self {
34            client,
35            params: CreateForumTopicParams {
36                chat_id: chat_id.into(),
37                name: name.into(),
38                icon_color: None,
39                icon_custom_emoji_id: None,
40            },
41        }
42    }
43    /// Sets the colour of the topic icon. One of: `0x6FB9F0`, `0xFFD67E`,
44    /// `0xCB86DB`, `0x8EEE98`, `0xFF93B2`, `0xFB6F5F`.
45    pub fn icon_color(mut self, color: u32) -> Self {
46        self.params.icon_color = Some(color);
47        self
48    }
49    /// Sets a custom emoji as the topic icon. Pass an empty string to remove it.
50    pub fn icon_custom_emoji_id(mut self, id: impl Into<String>) -> Self {
51        self.params.icon_custom_emoji_id = Some(id.into());
52        self
53    }
54}
55
56impl IntoFuture for CreateForumTopic {
57    type Output = Result<ForumTopic>;
58    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
59    fn into_future(self) -> Self::IntoFuture {
60        Box::pin(async move {
61            self.client
62                .post_json("createForumTopic", &self.params)
63                .await
64        })
65    }
66}
67
68// ─── editForumTopic ───────────────────────────────────────────────────────────
69
70#[derive(Serialize)]
71struct EditForumTopicParams {
72    chat_id: ChatId,
73    message_thread_id: i64,
74    #[serde(skip_serializing_if = "Option::is_none")]
75    name: Option<String>,
76    #[serde(skip_serializing_if = "Option::is_none")]
77    icon_custom_emoji_id: Option<String>,
78}
79
80/// Builder for the [`editForumTopic`](https://core.telegram.org/bots/api#editforumtopic) method.
81pub struct EditForumTopic {
82    client: BotClient,
83    params: EditForumTopicParams,
84}
85
86impl EditForumTopic {
87    pub(crate) fn new(
88        client: BotClient,
89        chat_id: impl Into<ChatId>,
90        message_thread_id: i64,
91    ) -> Self {
92        Self {
93            client,
94            params: EditForumTopicParams {
95                chat_id: chat_id.into(),
96                message_thread_id,
97                name: None,
98                icon_custom_emoji_id: None,
99            },
100        }
101    }
102    /// Sets the new name for the forum topic (1–128 characters).
103    pub fn name(mut self, n: impl Into<String>) -> Self {
104        self.params.name = Some(n.into());
105        self
106    }
107    /// Sets a new custom emoji for the topic icon. Pass an empty string to remove it.
108    pub fn icon_custom_emoji_id(mut self, id: impl Into<String>) -> Self {
109        self.params.icon_custom_emoji_id = Some(id.into());
110        self
111    }
112}
113
114impl IntoFuture for EditForumTopic {
115    type Output = Result<bool>;
116    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
117    fn into_future(self) -> Self::IntoFuture {
118        Box::pin(async move { self.client.post_json("editForumTopic", &self.params).await })
119    }
120}
121
122// ─── Thread-level forum actions (close/reopen/delete/unpin) ──────────────────
123
124#[derive(Serialize)]
125struct ForumThreadParams {
126    chat_id: ChatId,
127    message_thread_id: i64,
128}
129
130#[allow(dead_code)]
131macro_rules! forum_thread_action {
132    ($(#[$doc:meta])* $name:ident, $method:literal) => {
133        $(#[$doc])*
134        pub struct $name {
135            client: BotClient,
136            params: ForumThreadParams,
137        }
138
139        impl $name {
140            /// Creates a builder for the method.
141            pub fn new(
142                client: BotClient,
143                chat_id: impl Into<ChatId>,
144                message_thread_id: i64,
145            ) -> Self {
146                Self {
147                    client,
148                    params: ForumThreadParams {
149                        chat_id: chat_id.into(),
150                        message_thread_id,
151                    },
152                }
153            }
154        }
155
156        impl IntoFuture for $name {
157            type Output = Result<bool>;
158            type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
159            fn into_future(self) -> Self::IntoFuture {
160                Box::pin(async move { self.client.post_json($method, &self.params).await })
161            }
162        }
163    };
164}
165
166forum_thread_action!(
167    /// Builder for the [`closeForumTopic`](https://core.telegram.org/bots/api#closeforumtopic) method.
168    CloseForumTopic, "closeForumTopic");
169forum_thread_action!(
170    /// Builder for the [`reopenForumTopic`](https://core.telegram.org/bots/api#reopenforumtopic) method.
171    ReopenForumTopic, "reopenForumTopic");
172forum_thread_action!(
173    /// Builder for the [`deleteForumTopic`](https://core.telegram.org/bots/api#deleteforumtopic) method.
174    DeleteForumTopic, "deleteForumTopic");
175forum_thread_action!(
176    /// Builder for the [`unpinAllForumTopicMessages`](https://core.telegram.org/bots/api#unpinallforumtopicmessages) method.
177    UnpinAllForumTopicMessages, "unpinAllForumTopicMessages");
178
179// ─── General forum topic (chat-level) ─────────────────────────────────────────
180
181#[derive(Serialize)]
182struct ChatOnlyParams {
183    chat_id: ChatId,
184}
185
186macro_rules! chat_only_action {
187    ($(#[$doc:meta])* $name:ident, $method:literal) => {
188        $(#[$doc])*
189        pub struct $name {
190            client: BotClient,
191            params: ChatOnlyParams,
192        }
193        impl $name {
194            // Creates a builder for the method.
195            pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>) -> Self {
196                Self {
197                    client,
198                    params: ChatOnlyParams {
199                        chat_id: chat_id.into(),
200                    },
201                }
202            }
203        }
204        impl IntoFuture for $name {
205            type Output = Result<bool>;
206            type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
207            fn into_future(self) -> Self::IntoFuture {
208                Box::pin(async move { self.client.post_json($method, &self.params).await })
209            }
210        }
211    };
212}
213
214chat_only_action!(
215    /// Builder for the [`closeGeneralForumTopic`](https://core.telegram.org/bots/api#closegeneralforumtopic) method.
216    CloseGeneralForumTopic, "closeGeneralForumTopic");
217chat_only_action!(
218    /// Builder for the [`reopenGeneralForumTopic`](https://core.telegram.org/bots/api#reopengeneralforumtopic) method.
219    ReopenGeneralForumTopic, "reopenGeneralForumTopic");
220chat_only_action!(
221    /// Builder for the [`hideGeneralForumTopic`](https://core.telegram.org/bots/api#hidegeneralforumtopic) method.
222    HideGeneralForumTopic, "hideGeneralForumTopic");
223chat_only_action!(
224    /// Builder for the [`unhideGeneralForumTopic`](https://core.telegram.org/bots/api#unhidegeneralforumtopic) method.
225    UnhideGeneralForumTopic, "unhideGeneralForumTopic");
226
227// ─── editGeneralForumTopic ────────────────────────────────────────────────────
228
229#[derive(Serialize)]
230struct EditGeneralForumTopicParams {
231    chat_id: ChatId,
232    name: String,
233}
234
235/// Builder for the [`editGeneralForumTopic`](https://core.telegram.org/bots/api#editgeneralforumtopic) method.
236pub struct EditGeneralForumTopic {
237    client: BotClient,
238    params: EditGeneralForumTopicParams,
239}
240
241impl EditGeneralForumTopic {
242    pub(crate) fn new(
243        client: BotClient,
244        chat_id: impl Into<ChatId>,
245        name: impl Into<String>,
246    ) -> Self {
247        Self {
248            client,
249            params: EditGeneralForumTopicParams {
250                chat_id: chat_id.into(),
251                name: name.into(),
252            },
253        }
254    }
255}
256
257impl IntoFuture for EditGeneralForumTopic {
258    type Output = Result<bool>;
259    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
260    fn into_future(self) -> Self::IntoFuture {
261        Box::pin(async move {
262            self.client
263                .post_json("editGeneralForumTopic", &self.params)
264                .await
265        })
266    }
267}