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#[derive(Serialize)]
15#[serde(untagged)]
16pub enum EditTarget {
18 Chat {
20 chat_id: ChatId,
22 message_id: i64,
24 },
25 Inline {
27 inline_message_id: String,
29 },
30}
31
32#[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
51pub 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 pub fn parse_mode(mut self, m: ParseMode) -> Self {
102 self.params.parse_mode = Some(m);
103 self
104 }
105 pub fn entities(mut self, e: Vec<MessageEntity>) -> Self {
107 self.params.entities = Some(e);
108 self
109 }
110 pub fn link_preview_options(mut self, o: LinkPreviewOptions) -> Self {
112 self.params.link_preview_options = Some(o);
113 self
114 }
115 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#[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
150pub 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 pub fn caption(mut self, c: impl Into<String>) -> Self {
176 self.params.caption = Some(c.into());
177 self
178 }
179 pub fn parse_mode(mut self, m: ParseMode) -> Self {
181 self.params.parse_mode = Some(m);
182 self
183 }
184 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#[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
215pub 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 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
237 self.params.reply_markup = Some(m);
238 self
239 }
240 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#[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
279pub 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 pub fn live_period(mut self, v: u32) -> Self {
312 self.params.live_period = Some(v);
313 self
314 }
315 pub fn heading(mut self, v: u16) -> Self {
317 self.params.heading = Some(v);
318 self
319 }
320 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#[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
349pub 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 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}