1use crate::client::BotClient;
2use crate::error::Result;
3use rustigram_types::message::{MessageEntity, ParseMode};
4use serde::Serialize;
5use std::future::{Future, IntoFuture};
6use std::pin::Pin;
7
8macro_rules! impl_into_future {
12 ($builder:ident, $return_ty:ty, $method:literal) => {
13 impl IntoFuture for $builder {
14 type Output = Result<$return_ty>;
15 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
16
17 fn into_future(self) -> Self::IntoFuture {
18 Box::pin(async move { self.client.post_json($method, &self.params).await })
19 }
20 }
21 };
22}
23
24#[derive(Serialize)]
27struct PostStoryParams {
28 business_connection_id: String,
29 content: serde_json::Value,
35 active_period: u32,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 caption: Option<String>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 parse_mode: Option<ParseMode>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 caption_entities: Option<Vec<MessageEntity>>,
45 #[serde(skip_serializing_if = "Option::is_none")]
49 areas: Option<Vec<serde_json::Value>>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 post_to_chat_page: Option<bool>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 protect_content: Option<bool>,
54}
55
56pub struct PostStory {
64 client: BotClient,
65 params: PostStoryParams,
66}
67
68impl PostStory {
69 pub(crate) fn new(
70 client: BotClient,
71 business_connection_id: impl Into<String>,
72 content: serde_json::Value,
73 active_period: u32,
74 ) -> Self {
75 Self {
76 client,
77 params: PostStoryParams {
78 business_connection_id: business_connection_id.into(),
79 content,
80 active_period,
81 caption: None,
82 parse_mode: None,
83 caption_entities: None,
84 areas: None,
85 post_to_chat_page: None,
86 protect_content: None,
87 },
88 }
89 }
90 pub fn caption(mut self, c: impl Into<String>) -> Self {
92 self.params.caption = Some(c.into());
93 self
94 }
95 pub fn parse_mode(mut self, m: ParseMode) -> Self {
97 self.params.parse_mode = Some(m);
98 self
99 }
100 pub fn caption_entities(mut self, e: Vec<MessageEntity>) -> Self {
102 self.params.caption_entities = Some(e);
103 self
104 }
105 pub fn areas(mut self, a: Vec<serde_json::Value>) -> Self {
109 self.params.areas = Some(a);
110 self
111 }
112 pub fn post_to_chat_page(mut self, v: bool) -> Self {
114 self.params.post_to_chat_page = Some(v);
115 self
116 }
117 pub fn protect_content(mut self, v: bool) -> Self {
119 self.params.protect_content = Some(v);
120 self
121 }
122}
123
124impl_into_future!(PostStory, serde_json::Value, "postStory");
125
126#[derive(Serialize)]
129struct RepostStoryParams {
130 business_connection_id: String,
131 from_chat_id: i64,
132 from_story_id: i64,
133 active_period: u32,
137 #[serde(skip_serializing_if = "Option::is_none")]
138 post_to_chat_page: Option<bool>,
139 #[serde(skip_serializing_if = "Option::is_none")]
140 protect_content: Option<bool>,
141}
142
143pub struct RepostStory {
151 client: BotClient,
152 params: RepostStoryParams,
153}
154
155impl RepostStory {
156 pub(crate) fn new(
157 client: BotClient,
158 business_connection_id: impl Into<String>,
159 from_chat_id: i64,
160 from_story_id: i64,
161 active_period: u32,
162 ) -> Self {
163 Self {
164 client,
165 params: RepostStoryParams {
166 business_connection_id: business_connection_id.into(),
167 from_chat_id,
168 from_story_id,
169 active_period,
170 post_to_chat_page: None,
171 protect_content: None,
172 },
173 }
174 }
175 pub fn post_to_chat_page(mut self, v: bool) -> Self {
177 self.params.post_to_chat_page = Some(v);
178 self
179 }
180 pub fn protect_content(mut self, v: bool) -> Self {
182 self.params.protect_content = Some(v);
183 self
184 }
185}
186
187impl_into_future!(RepostStory, serde_json::Value, "repostStory");
188
189#[derive(Serialize)]
192struct EditStoryParams {
193 business_connection_id: String,
194 story_id: i64,
195 content: serde_json::Value,
199 #[serde(skip_serializing_if = "Option::is_none")]
200 caption: Option<String>,
201 #[serde(skip_serializing_if = "Option::is_none")]
202 parse_mode: Option<ParseMode>,
203 #[serde(skip_serializing_if = "Option::is_none")]
204 caption_entities: Option<Vec<MessageEntity>>,
205 #[serde(skip_serializing_if = "Option::is_none")]
209 areas: Option<Vec<serde_json::Value>>,
210}
211
212pub struct EditStory {
219 client: BotClient,
220 params: EditStoryParams,
221}
222
223impl EditStory {
224 pub(crate) fn new(
225 client: BotClient,
226 business_connection_id: impl Into<String>,
227 story_id: i64,
228 content: serde_json::Value,
229 ) -> Self {
230 Self {
231 client,
232 params: EditStoryParams {
233 business_connection_id: business_connection_id.into(),
234 story_id,
235 content,
236 caption: None,
237 parse_mode: None,
238 caption_entities: None,
239 areas: None,
240 },
241 }
242 }
243 pub fn caption(mut self, c: impl Into<String>) -> Self {
245 self.params.caption = Some(c.into());
246 self
247 }
248 pub fn parse_mode(mut self, m: ParseMode) -> Self {
250 self.params.parse_mode = Some(m);
251 self
252 }
253 pub fn caption_entities(mut self, e: Vec<MessageEntity>) -> Self {
255 self.params.caption_entities = Some(e);
256 self
257 }
258 pub fn areas(mut self, a: Vec<serde_json::Value>) -> Self {
262 self.params.areas = Some(a);
263 self
264 }
265}
266
267impl_into_future!(EditStory, serde_json::Value, "editStory");
268
269#[derive(Serialize)]
272struct DeleteStoryParams {
273 business_connection_id: String,
274 story_id: i64,
275}
276
277pub struct DeleteStory {
282 client: BotClient,
283 params: DeleteStoryParams,
284}
285
286impl DeleteStory {
287 pub(crate) fn new(
288 client: BotClient,
289 business_connection_id: impl Into<String>,
290 story_id: i64,
291 ) -> Self {
292 Self {
293 client,
294 params: DeleteStoryParams {
295 business_connection_id: business_connection_id.into(),
296 story_id,
297 },
298 }
299 }
300}
301
302impl_into_future!(DeleteStory, bool, "deleteStory");