use std::{error::Error, fmt};
use serde::{Deserialize, Serialize};
use crate::{
api::{Form, Method, Payload},
types::{ChatAdministratorRights, ChatId, InputProfilePhoto, InputProfilePhotoError, Integer, StarAmount, User},
};
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct Bot {
pub first_name: String,
pub id: Integer,
pub username: String,
pub allows_users_to_create_topics: bool,
pub can_connect_to_business: bool,
pub can_join_groups: bool,
pub can_manage_bots: bool,
pub can_read_all_group_messages: bool,
pub has_main_web_app: bool,
pub has_topics_enabled: bool,
pub last_name: Option<String>,
pub supports_inline_queries: bool,
}
impl Bot {
pub fn new<A, B>(id: Integer, username: A, first_name: B) -> Self
where
A: Into<String>,
B: Into<String>,
{
Self {
first_name: first_name.into(),
id,
username: username.into(),
allows_users_to_create_topics: false,
can_connect_to_business: false,
can_join_groups: false,
can_manage_bots: false,
can_read_all_group_messages: false,
has_main_web_app: false,
has_topics_enabled: false,
last_name: None,
supports_inline_queries: false,
}
}
pub fn with_allows_users_to_create_topics(mut self, value: bool) -> Self {
self.allows_users_to_create_topics = value;
self
}
pub fn with_can_connect_to_business(mut self, value: bool) -> Self {
self.can_connect_to_business = value;
self
}
pub fn with_can_join_groups(mut self, value: bool) -> Self {
self.can_join_groups = value;
self
}
pub fn with_can_manage_bots(mut self, value: bool) -> Self {
self.can_manage_bots = value;
self
}
pub fn with_can_read_all_group_messages(mut self, value: bool) -> Self {
self.can_read_all_group_messages = value;
self
}
pub fn with_has_main_web_app(mut self, value: bool) -> Self {
self.has_main_web_app = value;
self
}
pub fn with_has_topics_enabled(mut self, value: bool) -> Self {
self.has_topics_enabled = value;
self
}
pub fn with_last_name<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.last_name = Some(value.into());
self
}
pub fn with_supports_inline_queries(mut self, value: bool) -> Self {
self.supports_inline_queries = value;
self
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct BotCommand {
#[serde(rename = "command")]
name: String,
description: String,
}
impl BotCommand {
const MIN_NAME_LEN: usize = 1;
const MAX_NAME_LEN: usize = 32;
const MIN_DESCRIPTION_LEN: usize = 3;
const MAX_DESCRIPTION_LEN: usize = 256;
pub fn new<C, D>(name: C, description: D) -> Result<Self, BotCommandError>
where
C: Into<String>,
D: Into<String>,
{
let name = name.into();
let description = description.into();
let name_len = name.len();
let description_len = description.len();
if !(Self::MIN_NAME_LEN..=Self::MAX_NAME_LEN).contains(&name_len) {
Err(BotCommandError::BadNameLen(name_len))
} else if !(Self::MIN_DESCRIPTION_LEN..=Self::MAX_DESCRIPTION_LEN).contains(&description_len) {
Err(BotCommandError::BadDescriptionLen(description_len))
} else {
Ok(Self { name, description })
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn with_name<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.name = value.into();
self
}
pub fn description(&self) -> &str {
&self.description
}
pub fn with_description<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.description = value.into();
self
}
}
#[derive(Debug)]
pub enum BotCommandError {
BadNameLen(usize),
BadDescriptionLen(usize),
}
impl Error for BotCommandError {}
impl fmt::Display for BotCommandError {
fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
use self::BotCommandError::*;
match self {
BadNameLen(len) => write!(
out,
"command name can have a length of {} up to {} characters, got {}",
BotCommand::MIN_NAME_LEN,
BotCommand::MAX_NAME_LEN,
len
),
BadDescriptionLen(len) => write!(
out,
"command description can have a length of {} up to {} characters, got {}",
BotCommand::MIN_DESCRIPTION_LEN,
BotCommand::MAX_DESCRIPTION_LEN,
len
),
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum BotCommandScope {
AllChatAdministrators,
AllGroupChats,
AllPrivateChats,
Chat {
chat_id: ChatId,
},
ChatAdministrators {
chat_id: ChatId,
},
ChatMember {
chat_id: ChatId,
user_id: Integer,
},
Default,
}
impl BotCommandScope {
pub fn chat<T>(value: T) -> Self
where
T: Into<ChatId>,
{
Self::Chat { chat_id: value.into() }
}
pub fn chat_administrators<T>(value: T) -> Self
where
T: Into<ChatId>,
{
Self::ChatAdministrators { chat_id: value.into() }
}
pub fn chat_member<A>(chat_id: A, user_id: Integer) -> Self
where
A: Into<ChatId>,
{
Self::ChatMember {
chat_id: chat_id.into(),
user_id,
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct BotDescription {
pub description: String,
}
impl BotDescription {
pub fn new<T>(value: T) -> Self
where
T: Into<String>,
{
Self {
description: value.into(),
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct BotName {
pub name: String,
}
impl BotName {
pub fn new<T>(value: T) -> Self
where
T: Into<String>,
{
Self { name: value.into() }
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct BotShortDescription {
pub short_description: String,
}
impl BotShortDescription {
pub fn new<T>(value: T) -> Self
where
T: Into<String>,
{
Self {
short_description: value.into(),
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct ManagedBotUpdated {
pub bot: User,
pub user: User,
}
#[derive(Clone, Copy, Debug)]
pub struct Close;
impl Method for Close {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::empty("close")
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize)]
pub struct DeleteBotCommands {
language_code: Option<String>,
scope: Option<BotCommandScope>,
}
impl DeleteBotCommands {
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
pub fn with_scope(mut self, value: BotCommandScope) -> Self {
self.scope = Some(value);
self
}
}
impl Method for DeleteBotCommands {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::json("deleteMyCommands", self)
}
}
#[derive(Clone, Copy, Debug)]
pub struct GetBot;
impl Method for GetBot {
type Response = Bot;
fn into_payload(self) -> Payload {
Payload::empty("getMe")
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize)]
pub struct GetBotCommands {
language_code: Option<String>,
scope: Option<BotCommandScope>,
}
impl GetBotCommands {
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
pub fn with_scope(mut self, value: BotCommandScope) -> Self {
self.scope = Some(value);
self
}
}
impl Method for GetBotCommands {
type Response = Vec<BotCommand>;
fn into_payload(self) -> Payload {
Payload::json("getMyCommands", self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Copy, Debug, Default, Serialize)]
pub struct GetBotDefaultAdministratorRights {
for_channels: Option<bool>,
}
impl GetBotDefaultAdministratorRights {
pub fn with_for_channels(mut self, value: bool) -> Self {
self.for_channels = Some(value);
self
}
}
impl Method for GetBotDefaultAdministratorRights {
type Response = ChatAdministratorRights;
fn into_payload(self) -> Payload {
Payload::json("getMyDefaultAdministratorRights", self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize)]
pub struct GetBotDescription {
language_code: Option<String>,
}
impl GetBotDescription {
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
}
impl Method for GetBotDescription {
type Response = BotDescription;
fn into_payload(self) -> Payload {
Payload::json("getMyDescription", self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize)]
pub struct GetBotName {
language_code: Option<String>,
}
impl GetBotName {
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
}
impl Method for GetBotName {
type Response = BotName;
fn into_payload(self) -> Payload {
Payload::json("getMyName", self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize)]
pub struct GetBotShortDescription {
language_code: Option<String>,
}
impl GetBotShortDescription {
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
}
impl Method for GetBotShortDescription {
type Response = BotShortDescription;
fn into_payload(self) -> Payload {
Payload::json("getMyShortDescription", self)
}
}
#[derive(Clone, Copy, Debug)]
pub struct GetBotStarBalance;
impl Method for GetBotStarBalance {
type Response = StarAmount;
fn into_payload(self) -> Payload {
Payload::empty("getMyStarBalance")
}
}
#[derive(Clone, Copy, Debug, Serialize)]
pub struct GetManagedBotToken {
user_id: Integer,
}
impl From<Integer> for GetManagedBotToken {
fn from(value: Integer) -> Self {
Self { user_id: value }
}
}
impl Method for GetManagedBotToken {
type Response = String;
fn into_payload(self) -> Payload {
Payload::json("getManagedBotToken", self)
}
}
#[derive(Clone, Copy, Debug)]
pub struct LogOut;
impl Method for LogOut {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::empty("logOut")
}
}
#[derive(Clone, Copy, Debug, Serialize)]
pub struct ReplaceManagedBotToken {
user_id: Integer,
}
impl From<Integer> for ReplaceManagedBotToken {
fn from(value: Integer) -> Self {
Self { user_id: value }
}
}
impl Method for ReplaceManagedBotToken {
type Response = String;
fn into_payload(self) -> Payload {
Payload::json("replaceManagedBotToken", self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Serialize)]
pub struct SetBotCommands {
commands: Vec<BotCommand>,
language_code: Option<String>,
scope: Option<BotCommandScope>,
}
impl SetBotCommands {
pub fn new(commands: impl IntoIterator<Item = BotCommand>) -> Self {
Self {
commands: commands.into_iter().collect(),
language_code: None,
scope: None,
}
}
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
pub fn with_scope(mut self, value: BotCommandScope) -> Self {
self.scope = Some(value);
self
}
}
impl Method for SetBotCommands {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::json("setMyCommands", self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Copy, Debug, Default, Serialize)]
pub struct SetBotDefaultAdministratorRights {
for_channels: Option<bool>,
rights: Option<ChatAdministratorRights>,
}
impl SetBotDefaultAdministratorRights {
pub fn with_for_channels(mut self, value: bool) -> Self {
self.for_channels = Some(value);
self
}
pub fn with_rights(mut self, value: ChatAdministratorRights) -> Self {
self.rights = Some(value);
self
}
}
impl Method for SetBotDefaultAdministratorRights {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::json("setMyDefaultAdministratorRights", self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize)]
pub struct SetBotDescription {
description: Option<String>,
language_code: Option<String>,
}
impl SetBotDescription {
pub fn with_description<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.description = Some(value.into());
self
}
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
}
impl Method for SetBotDescription {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::json("setMyDescription", self)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize)]
pub struct SetBotName {
language_code: Option<String>,
name: Option<String>,
}
impl SetBotName {
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
pub fn with_name<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.name = Some(value.into());
self
}
}
impl Method for SetBotName {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::json("setMyName", self)
}
}
#[derive(Debug)]
pub struct SetBotProfilePhoto {
form: Form,
}
impl SetBotProfilePhoto {
pub fn new<T>(photo: T) -> Result<Self, InputProfilePhotoError>
where
T: Into<InputProfilePhoto>,
{
let form = Form::try_from(photo.into())?;
Ok(Self { form })
}
}
impl Method for SetBotProfilePhoto {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::form("setMyProfilePhoto", self.form)
}
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize)]
pub struct SetBotShortDescription {
language_code: Option<String>,
short_description: Option<String>,
}
impl SetBotShortDescription {
pub fn with_language_code<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.language_code = Some(value.into());
self
}
pub fn with_short_description<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.short_description = Some(value.into());
self
}
}
impl Method for SetBotShortDescription {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::json("setMyShortDescription", self)
}
}
#[derive(Clone, Copy, Debug, Serialize)]
pub struct RemoveBotProfilePhoto;
impl Method for RemoveBotProfilePhoto {
type Response = bool;
fn into_payload(self) -> Payload {
Payload::empty("removeMyProfilePhoto")
}
}