use crate::client::BotClient;
use crate::error::Result;
use rustigram_types::forum::ForumTopic;
use rustigram_types::user::ChatId;
use serde::Serialize;
use std::future::{Future, IntoFuture};
use std::pin::Pin;
#[derive(Serialize)]
struct CreateForumTopicParams {
chat_id: ChatId,
name: String,
#[serde(skip_serializing_if = "Option::is_none")]
icon_color: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
icon_custom_emoji_id: Option<String>,
}
pub struct CreateForumTopic {
client: BotClient,
params: CreateForumTopicParams,
}
impl CreateForumTopic {
pub(crate) fn new(
client: BotClient,
chat_id: impl Into<ChatId>,
name: impl Into<String>,
) -> Self {
Self {
client,
params: CreateForumTopicParams {
chat_id: chat_id.into(),
name: name.into(),
icon_color: None,
icon_custom_emoji_id: None,
},
}
}
pub fn icon_color(mut self, color: u32) -> Self {
self.params.icon_color = Some(color);
self
}
pub fn icon_custom_emoji_id(mut self, id: impl Into<String>) -> Self {
self.params.icon_custom_emoji_id = Some(id.into());
self
}
}
impl IntoFuture for CreateForumTopic {
type Output = Result<ForumTopic>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
self.client
.post_json("createForumTopic", &self.params)
.await
})
}
}
#[derive(Serialize)]
struct EditForumTopicParams {
chat_id: ChatId,
message_thread_id: i64,
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
icon_custom_emoji_id: Option<String>,
}
pub struct EditForumTopic {
client: BotClient,
params: EditForumTopicParams,
}
impl EditForumTopic {
pub(crate) fn new(
client: BotClient,
chat_id: impl Into<ChatId>,
message_thread_id: i64,
) -> Self {
Self {
client,
params: EditForumTopicParams {
chat_id: chat_id.into(),
message_thread_id,
name: None,
icon_custom_emoji_id: None,
},
}
}
pub fn name(mut self, n: impl Into<String>) -> Self {
self.params.name = Some(n.into());
self
}
pub fn icon_custom_emoji_id(mut self, id: impl Into<String>) -> Self {
self.params.icon_custom_emoji_id = Some(id.into());
self
}
}
impl IntoFuture for EditForumTopic {
type Output = Result<bool>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move { self.client.post_json("editForumTopic", &self.params).await })
}
}
#[derive(Serialize)]
struct ForumThreadParams {
chat_id: ChatId,
message_thread_id: i64,
}
#[allow(dead_code)]
macro_rules! forum_thread_action {
($(#[$doc:meta])* $name:ident, $method:literal) => {
$(#[$doc])*
pub struct $name {
client: BotClient,
params: ForumThreadParams,
}
impl $name {
pub fn new(
client: BotClient,
chat_id: impl Into<ChatId>,
message_thread_id: i64,
) -> Self {
Self {
client,
params: ForumThreadParams {
chat_id: chat_id.into(),
message_thread_id,
},
}
}
}
impl IntoFuture for $name {
type Output = Result<bool>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move { self.client.post_json($method, &self.params).await })
}
}
};
}
forum_thread_action!(
CloseForumTopic, "closeForumTopic");
forum_thread_action!(
ReopenForumTopic, "reopenForumTopic");
forum_thread_action!(
DeleteForumTopic, "deleteForumTopic");
forum_thread_action!(
UnpinAllForumTopicMessages, "unpinAllForumTopicMessages");
#[derive(Serialize)]
struct ChatOnlyParams {
chat_id: ChatId,
}
macro_rules! chat_only_action {
($(#[$doc:meta])* $name:ident, $method:literal) => {
$(#[$doc])*
pub struct $name {
client: BotClient,
params: ChatOnlyParams,
}
impl $name {
pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>) -> Self {
Self {
client,
params: ChatOnlyParams {
chat_id: chat_id.into(),
},
}
}
}
impl IntoFuture for $name {
type Output = Result<bool>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move { self.client.post_json($method, &self.params).await })
}
}
};
}
chat_only_action!(
CloseGeneralForumTopic, "closeGeneralForumTopic");
chat_only_action!(
ReopenGeneralForumTopic, "reopenGeneralForumTopic");
chat_only_action!(
HideGeneralForumTopic, "hideGeneralForumTopic");
chat_only_action!(
UnhideGeneralForumTopic, "unhideGeneralForumTopic");
#[derive(Serialize)]
struct EditGeneralForumTopicParams {
chat_id: ChatId,
name: String,
}
pub struct EditGeneralForumTopic {
client: BotClient,
params: EditGeneralForumTopicParams,
}
impl EditGeneralForumTopic {
pub(crate) fn new(
client: BotClient,
chat_id: impl Into<ChatId>,
name: impl Into<String>,
) -> Self {
Self {
client,
params: EditGeneralForumTopicParams {
chat_id: chat_id.into(),
name: name.into(),
},
}
}
}
impl IntoFuture for EditGeneralForumTopic {
type Output = Result<bool>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
self.client
.post_json("editGeneralForumTopic", &self.params)
.await
})
}
}
chat_only_action!(
UnpinAllGeneralForumTopicMessages, "unpinAllGeneralForumTopicMessages");