use crate::client::BotClient;
use crate::error::Result;
use reqwest::multipart::{Form, Part};
use rustigram_types::keyboard::MenuButton;
use rustigram_types::user::{
BotCommand, BotCommandScope, BotDescription, BotName, BotShortDescription,
ChatAdministratorRights, ChatId,
};
use serde::Serialize;
use std::future::{Future, IntoFuture};
use std::pin::Pin;
macro_rules! impl_into_future {
($builder:ident, $return_ty:ty, $method:literal) => {
impl IntoFuture for $builder {
type Output = Result<$return_ty>;
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 })
}
}
};
}
#[derive(Serialize)]
struct SetMyCommandsParams {
commands: Vec<BotCommand>,
#[serde(skip_serializing_if = "Option::is_none")]
scope: Option<BotCommandScope>,
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct SetMyCommands {
client: BotClient,
params: SetMyCommandsParams,
}
impl SetMyCommands {
pub(crate) fn new(client: BotClient, commands: Vec<BotCommand>) -> Self {
Self {
client,
params: SetMyCommandsParams {
commands,
scope: None,
language_code: None,
},
}
}
pub fn scope(mut self, s: BotCommandScope) -> Self {
self.params.scope = Some(s);
self
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(SetMyCommands, bool, "setMyCommands");
#[derive(Serialize, Default)]
struct DeleteMyCommandsParams {
#[serde(skip_serializing_if = "Option::is_none")]
scope: Option<BotCommandScope>,
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct DeleteMyCommands {
client: BotClient,
params: DeleteMyCommandsParams,
}
impl DeleteMyCommands {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn scope(mut self, s: BotCommandScope) -> Self {
self.params.scope = Some(s);
self
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(DeleteMyCommands, bool, "deleteMyCommands");
#[derive(Serialize, Default)]
struct GetMyCommandsParams {
#[serde(skip_serializing_if = "Option::is_none")]
scope: Option<BotCommandScope>,
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct GetMyCommands {
client: BotClient,
params: GetMyCommandsParams,
}
impl GetMyCommands {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn scope(mut self, s: BotCommandScope) -> Self {
self.params.scope = Some(s);
self
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(GetMyCommands, Vec<BotCommand>, "getMyCommands");
#[derive(Serialize, Default)]
struct SetMyNameParams {
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct SetMyName {
client: BotClient,
params: SetMyNameParams,
}
impl SetMyName {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn name(mut self, n: impl Into<String>) -> Self {
self.params.name = Some(n.into());
self
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(SetMyName, bool, "setMyName");
#[derive(Serialize, Default)]
struct GetMyNameParams {
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct GetMyName {
client: BotClient,
params: GetMyNameParams,
}
impl GetMyName {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(GetMyName, BotName, "getMyName");
#[derive(Serialize, Default)]
struct SetMyDescriptionParams {
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct SetMyDescription {
client: BotClient,
params: SetMyDescriptionParams,
}
impl SetMyDescription {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn description(mut self, d: impl Into<String>) -> Self {
self.params.description = Some(d.into());
self
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(SetMyDescription, bool, "setMyDescription");
#[derive(Serialize, Default)]
struct GetMyDescriptionParams {
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct GetMyDescription {
client: BotClient,
params: GetMyDescriptionParams,
}
impl GetMyDescription {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(GetMyDescription, BotDescription, "getMyDescription");
#[derive(Serialize, Default)]
struct SetMyShortDescriptionParams {
#[serde(skip_serializing_if = "Option::is_none")]
short_description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct SetMyShortDescription {
client: BotClient,
params: SetMyShortDescriptionParams,
}
impl SetMyShortDescription {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn short_description(mut self, d: impl Into<String>) -> Self {
self.params.short_description = Some(d.into());
self
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(SetMyShortDescription, bool, "setMyShortDescription");
#[derive(Serialize, Default)]
struct GetMyShortDescriptionParams {
#[serde(skip_serializing_if = "Option::is_none")]
language_code: Option<String>,
}
pub struct GetMyShortDescription {
client: BotClient,
params: GetMyShortDescriptionParams,
}
impl GetMyShortDescription {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn language_code(mut self, lc: impl Into<String>) -> Self {
self.params.language_code = Some(lc.into());
self
}
}
impl_into_future!(
GetMyShortDescription,
BotShortDescription,
"getMyShortDescription"
);
#[derive(Serialize, Default)]
struct SetMyDefaultAdministratorRightsParams {
#[serde(skip_serializing_if = "Option::is_none")]
rights: Option<ChatAdministratorRights>,
#[serde(skip_serializing_if = "Option::is_none")]
for_channels: Option<bool>,
}
pub struct SetMyDefaultAdministratorRights {
client: BotClient,
params: SetMyDefaultAdministratorRightsParams,
}
impl SetMyDefaultAdministratorRights {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn rights(mut self, r: ChatAdministratorRights) -> Self {
self.params.rights = Some(r);
self
}
pub fn for_channels(mut self, v: bool) -> Self {
self.params.for_channels = Some(v);
self
}
}
impl_into_future!(
SetMyDefaultAdministratorRights,
bool,
"setMyDefaultAdministratorRights"
);
#[derive(Serialize, Default)]
struct GetMyDefaultAdministratorRightsParams {
#[serde(skip_serializing_if = "Option::is_none")]
for_channels: Option<bool>,
}
pub struct GetMyDefaultAdministratorRights {
client: BotClient,
params: GetMyDefaultAdministratorRightsParams,
}
impl GetMyDefaultAdministratorRights {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn for_channels(mut self, v: bool) -> Self {
self.params.for_channels = Some(v);
self
}
}
impl_into_future!(
GetMyDefaultAdministratorRights,
ChatAdministratorRights,
"getMyDefaultAdministratorRights"
);
#[derive(Serialize, Default)]
struct GetChatMenuButtonParams {
#[serde(skip_serializing_if = "Option::is_none")]
chat_id: Option<ChatId>,
}
pub struct GetChatMenuButton {
client: BotClient,
params: GetChatMenuButtonParams,
}
impl GetChatMenuButton {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn chat_id(mut self, id: impl Into<ChatId>) -> Self {
self.params.chat_id = Some(id.into());
self
}
}
impl_into_future!(GetChatMenuButton, MenuButton, "getChatMenuButton");
#[derive(Serialize, Default)]
struct SetChatMenuButtonParams {
#[serde(skip_serializing_if = "Option::is_none")]
chat_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
menu_button: Option<MenuButton>,
}
pub struct SetChatMenuButton {
client: BotClient,
params: SetChatMenuButtonParams,
}
impl SetChatMenuButton {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn chat_id(mut self, id: i64) -> Self {
self.params.chat_id = Some(id);
self
}
pub fn menu_button(mut self, btn: MenuButton) -> Self {
self.params.menu_button = Some(btn);
self
}
}
impl_into_future!(SetChatMenuButton, bool, "setChatMenuButton");
pub struct LogOut {
client: BotClient,
}
impl LogOut {
pub(crate) fn new(client: BotClient) -> Self {
Self { client }
}
}
impl IntoFuture for LogOut {
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("logOut", &serde_json::json!({}))
.await
})
}
}
pub struct Close {
client: BotClient,
}
impl Close {
pub(crate) fn new(client: BotClient) -> Self {
Self { client }
}
}
impl IntoFuture for Close {
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("close", &serde_json::json!({})).await })
}
}
pub struct SetMyProfilePhoto {
client: BotClient,
photo_json: String,
}
impl SetMyProfilePhoto {
pub(crate) fn new(client: BotClient, photo_json: String) -> Self {
Self { client, photo_json }
}
}
impl IntoFuture for SetMyProfilePhoto {
type Output = Result<bool>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
let part = Part::text(self.photo_json)
.mime_str("application/json")
.map_err(|e| crate::error::Error::Decode(e.to_string()))?;
let form = Form::new().part("photo", part);
self.client.post_multipart("setMyProfilePhoto", form).await
})
}
}
pub struct RemoveMyProfilePhoto {
client: BotClient,
}
impl RemoveMyProfilePhoto {
pub(crate) fn new(client: BotClient) -> Self {
Self { client }
}
}
impl IntoFuture for RemoveMyProfilePhoto {
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("removeMyProfilePhoto", &serde_json::json!({}))
.await
})
}
}
#[derive(Serialize)]
struct ReplaceManagedBotTokenParams {
user_id: i64,
}
pub struct ReplaceManagedBotToken {
client: BotClient,
params: ReplaceManagedBotTokenParams,
}
impl ReplaceManagedBotToken {
pub(crate) fn new(client: BotClient, user_id: i64) -> Self {
Self {
client,
params: ReplaceManagedBotTokenParams { user_id },
}
}
}
impl_into_future!(ReplaceManagedBotToken, String, "replaceManagedBotToken");
#[derive(Serialize)]
struct GetManagedBotTokenParams {
user_id: i64,
}
pub struct GetManagedBotToken {
client: BotClient,
params: GetManagedBotTokenParams,
}
impl GetManagedBotToken {
pub(crate) fn new(client: BotClient, user_id: i64) -> Self {
Self {
client,
params: GetManagedBotTokenParams { user_id },
}
}
}
impl_into_future!(GetManagedBotToken, String, "getManagedBotToken");