Skip to main content

rustigram_api/methods/
editing.rs

1use std::future::{Future, IntoFuture};
2use std::pin::Pin;
3
4use serde::Serialize;
5
6use rustigram_types::keyboard::InlineKeyboardMarkup;
7use rustigram_types::message::{LinkPreviewOptions, Message, MessageEntity, ParseMode};
8use rustigram_types::user::ChatId;
9
10use crate::client::BotClient;
11use crate::error::Result;
12
13/// Target identifier for inline message edits.
14#[derive(Serialize)]
15#[serde(untagged)]
16/// Identifies the target message — either a chat message or an inline message.
17pub enum EditTarget {
18    /// Targets a regular chat message.
19    Chat {
20        /// The chat containing the message.
21        chat_id: ChatId,
22        /// Identifier of the message to edit.
23        message_id: i64,
24    },
25    /// Targets an inline message sent via inline mode.
26    Inline {
27        /// Identifier of the inline message.
28        inline_message_id: String,
29    },
30}
31
32// ─── editMessageText ──────────────────────────────────────────────────────────
33
34#[derive(Serialize)]
35struct EditMessageTextParams {
36    #[serde(flatten)]
37    target: EditTarget,
38    text: String,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    business_connection_id: Option<String>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    parse_mode: Option<ParseMode>,
43    #[serde(skip_serializing_if = "Option::is_none")]
44    entities: Option<Vec<MessageEntity>>,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    link_preview_options: Option<LinkPreviewOptions>,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    reply_markup: Option<InlineKeyboardMarkup>,
49}
50
51/// Builder for the [`editMessageText`](https://core.telegram.org/bots/api#editmessagetext) method.
52pub struct EditMessageText {
53    client: BotClient,
54    params: EditMessageTextParams,
55}
56
57impl EditMessageText {
58    pub(crate) fn in_chat(
59        client: BotClient,
60        chat_id: impl Into<ChatId>,
61        message_id: i64,
62        text: impl Into<String>,
63    ) -> Self {
64        Self {
65            client,
66            params: EditMessageTextParams {
67                target: EditTarget::Chat {
68                    chat_id: chat_id.into(),
69                    message_id,
70                },
71                text: text.into(),
72                business_connection_id: None,
73                parse_mode: None,
74                entities: None,
75                link_preview_options: None,
76                reply_markup: None,
77            },
78        }
79    }
80    pub(crate) fn inline(
81        client: BotClient,
82        inline_message_id: impl Into<String>,
83        text: impl Into<String>,
84    ) -> Self {
85        Self {
86            client,
87            params: EditMessageTextParams {
88                target: EditTarget::Inline {
89                    inline_message_id: inline_message_id.into(),
90                },
91                text: text.into(),
92                business_connection_id: None,
93                parse_mode: None,
94                entities: None,
95                link_preview_options: None,
96                reply_markup: None,
97            },
98        }
99    }
100    /// Sets the text parse mode (`MarkdownV2`, `HTML`, or `Markdown`).
101    pub fn parse_mode(mut self, m: ParseMode) -> Self {
102        self.params.parse_mode = Some(m);
103        self
104    }
105    /// Sets custom entities instead of using a parse mode.
106    pub fn entities(mut self, e: Vec<MessageEntity>) -> Self {
107        self.params.entities = Some(e);
108        self
109    }
110    /// Configures link preview options for the edited message.
111    pub fn link_preview_options(mut self, o: LinkPreviewOptions) -> Self {
112        self.params.link_preview_options = Some(o);
113        self
114    }
115    /// Attaches a reply markup (inline keyboard, reply keyboard, etc.).
116    pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
117        self.params.reply_markup = Some(m);
118        self
119    }
120}
121
122impl IntoFuture for EditMessageText {
123    type Output = Result<Message>;
124    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
125    fn into_future(self) -> Self::IntoFuture {
126        Box::pin(async move { self.client.post_json("editMessageText", &self.params).await })
127    }
128}
129
130// ─── editMessageCaption ───────────────────────────────────────────────────────
131
132#[derive(Serialize)]
133struct EditMessageCaptionParams {
134    #[serde(flatten)]
135    target: EditTarget,
136    #[serde(skip_serializing_if = "Option::is_none")]
137    business_connection_id: Option<String>,
138    #[serde(skip_serializing_if = "Option::is_none")]
139    caption: Option<String>,
140    #[serde(skip_serializing_if = "Option::is_none")]
141    parse_mode: Option<ParseMode>,
142    #[serde(skip_serializing_if = "Option::is_none")]
143    caption_entities: Option<Vec<MessageEntity>>,
144    #[serde(skip_serializing_if = "Option::is_none")]
145    show_caption_above_media: Option<bool>,
146    #[serde(skip_serializing_if = "Option::is_none")]
147    reply_markup: Option<InlineKeyboardMarkup>,
148}
149
150/// Builder for the [`editMessageCaption`](https://core.telegram.org/bots/api#editmessagecaption) method.
151pub struct EditMessageCaption {
152    client: BotClient,
153    params: EditMessageCaptionParams,
154}
155
156impl EditMessageCaption {
157    pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
158        Self {
159            client,
160            params: EditMessageCaptionParams {
161                target: EditTarget::Chat {
162                    chat_id: chat_id.into(),
163                    message_id,
164                },
165                business_connection_id: None,
166                caption: None,
167                parse_mode: None,
168                caption_entities: None,
169                show_caption_above_media: None,
170                reply_markup: None,
171            },
172        }
173    }
174    /// Sets the new caption text (0–1024 characters).
175    pub fn caption(mut self, c: impl Into<String>) -> Self {
176        self.params.caption = Some(c.into());
177        self
178    }
179    /// Sets the caption parse mode (`MarkdownV2`, `HTML`, or `Markdown`).
180    pub fn parse_mode(mut self, m: ParseMode) -> Self {
181        self.params.parse_mode = Some(m);
182        self
183    }
184    /// Attaches a reply markup (inline keyboard, reply keyboard, etc.).
185    pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
186        self.params.reply_markup = Some(m);
187        self
188    }
189}
190
191impl IntoFuture for EditMessageCaption {
192    type Output = Result<Message>;
193    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
194    fn into_future(self) -> Self::IntoFuture {
195        Box::pin(async move {
196            self.client
197                .post_json("editMessageCaption", &self.params)
198                .await
199        })
200    }
201}
202
203// ─── editMessageReplyMarkup ───────────────────────────────────────────────────
204
205#[derive(Serialize)]
206struct EditMessageReplyMarkupParams {
207    #[serde(flatten)]
208    target: EditTarget,
209    #[serde(skip_serializing_if = "Option::is_none")]
210    business_connection_id: Option<String>,
211    #[serde(skip_serializing_if = "Option::is_none")]
212    reply_markup: Option<InlineKeyboardMarkup>,
213}
214
215/// Builder for the [`editMessageReplyMarkup`](https://core.telegram.org/bots/api#editmessagereplymarkup) method.
216pub struct EditMessageReplyMarkup {
217    client: BotClient,
218    params: EditMessageReplyMarkupParams,
219}
220
221impl EditMessageReplyMarkup {
222    pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
223        Self {
224            client,
225            params: EditMessageReplyMarkupParams {
226                target: EditTarget::Chat {
227                    chat_id: chat_id.into(),
228                    message_id,
229                },
230                business_connection_id: None,
231                reply_markup: None,
232            },
233        }
234    }
235    /// Attaches a reply markup (inline keyboard, reply keyboard, etc.).
236    pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
237        self.params.reply_markup = Some(m);
238        self
239    }
240    /// Removes the inline keyboard from the message.
241    pub fn remove_markup(mut self) -> Self {
242        self.params.reply_markup = None;
243        self
244    }
245}
246
247impl IntoFuture for EditMessageReplyMarkup {
248    type Output = Result<Message>;
249    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
250    fn into_future(self) -> Self::IntoFuture {
251        Box::pin(async move {
252            self.client
253                .post_json("editMessageReplyMarkup", &self.params)
254                .await
255        })
256    }
257}
258
259// ─── editMessageLiveLocation ──────────────────────────────────────────────────
260
261#[derive(Serialize)]
262struct EditMessageLiveLocationParams {
263    #[serde(flatten)]
264    target: EditTarget,
265    latitude: f64,
266    longitude: f64,
267    #[serde(skip_serializing_if = "Option::is_none")]
268    live_period: Option<u32>,
269    #[serde(skip_serializing_if = "Option::is_none")]
270    horizontal_accuracy: Option<f64>,
271    #[serde(skip_serializing_if = "Option::is_none")]
272    heading: Option<u16>,
273    #[serde(skip_serializing_if = "Option::is_none")]
274    proximity_alert_radius: Option<u32>,
275    #[serde(skip_serializing_if = "Option::is_none")]
276    reply_markup: Option<InlineKeyboardMarkup>,
277}
278
279/// Builder for the [`editMessageLiveLocation`](https://core.telegram.org/bots/api#editmessagelivelocation) method.
280pub struct EditMessageLiveLocation {
281    client: BotClient,
282    params: EditMessageLiveLocationParams,
283}
284
285impl EditMessageLiveLocation {
286    pub(crate) fn in_chat(
287        client: BotClient,
288        chat_id: impl Into<ChatId>,
289        message_id: i64,
290        latitude: f64,
291        longitude: f64,
292    ) -> Self {
293        Self {
294            client,
295            params: EditMessageLiveLocationParams {
296                target: EditTarget::Chat {
297                    chat_id: chat_id.into(),
298                    message_id,
299                },
300                latitude,
301                longitude,
302                live_period: None,
303                horizontal_accuracy: None,
304                heading: None,
305                proximity_alert_radius: None,
306                reply_markup: None,
307            },
308        }
309    }
310    /// Sets how long the location stays live, in seconds (60–86400).
311    pub fn live_period(mut self, v: u32) -> Self {
312        self.params.live_period = Some(v);
313        self
314    }
315    /// Sets the direction of movement in degrees (1–360).
316    pub fn heading(mut self, v: u16) -> Self {
317        self.params.heading = Some(v);
318        self
319    }
320    /// Attaches a reply markup (inline keyboard, reply keyboard, etc.).
321    pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
322        self.params.reply_markup = Some(m);
323        self
324    }
325}
326
327impl IntoFuture for EditMessageLiveLocation {
328    type Output = Result<Message>;
329    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
330    fn into_future(self) -> Self::IntoFuture {
331        Box::pin(async move {
332            self.client
333                .post_json("editMessageLiveLocation", &self.params)
334                .await
335        })
336    }
337}
338
339// ─── stopMessageLiveLocation ──────────────────────────────────────────────────
340
341#[derive(Serialize)]
342struct StopMessageLiveLocationParams {
343    #[serde(flatten)]
344    target: EditTarget,
345    #[serde(skip_serializing_if = "Option::is_none")]
346    reply_markup: Option<InlineKeyboardMarkup>,
347}
348
349/// Builder for the [`stopMessageLiveLocation`](https://core.telegram.org/bots/api#stopmessagelivelocation) method.
350pub struct StopMessageLiveLocation {
351    client: BotClient,
352    params: StopMessageLiveLocationParams,
353}
354
355impl StopMessageLiveLocation {
356    pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
357        Self {
358            client,
359            params: StopMessageLiveLocationParams {
360                target: EditTarget::Chat {
361                    chat_id: chat_id.into(),
362                    message_id,
363                },
364                reply_markup: None,
365            },
366        }
367    }
368    /// Attaches a reply markup (inline keyboard, reply keyboard, etc.).
369    pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
370        self.params.reply_markup = Some(m);
371        self
372    }
373}
374
375impl IntoFuture for StopMessageLiveLocation {
376    type Output = Result<Message>;
377    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
378    fn into_future(self) -> Self::IntoFuture {
379        Box::pin(async move {
380            self.client
381                .post_json("stopMessageLiveLocation", &self.params)
382                .await
383        })
384    }
385}