mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
Merge branch 'dev' into conversion_traits_for_parse_mode
This commit is contained in:
commit
585c161511
25 changed files with 306 additions and 50 deletions
|
@ -18,7 +18,8 @@ use crate::{
|
|||
RestrictChatMember, SendAnimation, SendAudio, SendChatAction,
|
||||
SendContact, SendDocument, SendGame, SendInvoice, SendLocation,
|
||||
SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendSticker,
|
||||
SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription,
|
||||
SendVenue, SendVideo, SendVideoNote, SendVoice,
|
||||
SetChatAdministratorCustomTitle, SetChatDescription,
|
||||
SetChatPermission, SetChatPhoto, SetChatStickerSet, SetChatTitle,
|
||||
SetGameScore, SetGameScoreInline, SetStickerPositionInSet,
|
||||
SetWebhook, StopMessageLiveLocation, StopMessageLiveLocationInline,
|
||||
|
@ -1150,4 +1151,28 @@ impl Bot {
|
|||
GetGameHighScore::new(chat_id, message_id, user_id),
|
||||
)
|
||||
}
|
||||
|
||||
/// For tg-method documentation see [`SetChatAdministratorCustomTitle`]
|
||||
///
|
||||
/// [`SetChatAdministratorCustomTitle`]:
|
||||
/// crate::requests::payloads::SetChatAdministratorCustomTitle
|
||||
pub fn set_chat_administrator_custom_title<C, CT>(
|
||||
&self,
|
||||
chat_id: C,
|
||||
user_id: i32,
|
||||
custom_title: CT,
|
||||
) -> json::Request<SetChatAdministratorCustomTitle>
|
||||
where
|
||||
C: Into<ChatId>,
|
||||
CT: Into<String>,
|
||||
{
|
||||
json::Request::new(
|
||||
self,
|
||||
SetChatAdministratorCustomTitle::new(
|
||||
chat_id,
|
||||
user_id,
|
||||
custom_title,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ type FiltersWithHandlers<'a, T, E> = Vec<FilterWithHandler<'a, T, E>>;
|
|||
/// acts:
|
||||
///
|
||||
/// <div align="center">
|
||||
/// <img src="https://github.com/teloxide/teloxide/blob/dev/media/FILTER_DP_FLOWCHART.png" width="700" />
|
||||
/// <img src="https://raw.githubusercontent.com/teloxide/teloxide/dev/media/FILTER_DP_FLOWCHART.png" width="700" />
|
||||
/// </div>
|
||||
///
|
||||
/// ## Examples
|
||||
|
@ -69,8 +69,10 @@ type FiltersWithHandlers<'a, T, E> = Vec<FilterWithHandler<'a, T, E>>;
|
|||
/// ```
|
||||
///
|
||||
/// [`std::fmt::Debug`]: std::fmt::Debug
|
||||
/// [updater]: crate::dispatching::updater
|
||||
/// [`.dispatch(updater)`]: FilterDispatcher::dispatch
|
||||
/// [`ErrorHandler`]: crate::dispatching::error_handlers::ErrorHandler
|
||||
/// [`Updater`]: crate::dispatching::updaters::Updater
|
||||
/// [`Handler`]: crate::dispatching::Handler
|
||||
pub struct FilterDispatcher<'a, E, Eh> {
|
||||
message_handlers: FiltersWithHandlers<'a, Message, E>,
|
||||
edited_message_handlers: FiltersWithHandlers<'a, Message, E>,
|
1
src/dispatching/dispatchers/mod.rs
Normal file
1
src/dispatching/dispatchers/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod filter;
|
|
@ -1,13 +1,13 @@
|
|||
//! Update dispatching.
|
||||
|
||||
mod dispatchers;
|
||||
pub mod error_handlers;
|
||||
mod filter_dp;
|
||||
pub mod filters;
|
||||
mod handler;
|
||||
pub mod updaters;
|
||||
|
||||
pub use dispatchers::filter::FilterDispatcher;
|
||||
pub use error_handlers::ErrorHandler;
|
||||
pub use filter_dp::FilterDispatcher;
|
||||
pub use filters::Filter;
|
||||
pub use handler::Handler;
|
||||
pub use updaters::Updater;
|
||||
|
|
|
@ -123,7 +123,9 @@ impl IntoFormValue for str {
|
|||
impl IntoFormValue for ParseMode {
|
||||
fn into_form_value(&self) -> Option<FormValue> {
|
||||
let string = match self {
|
||||
ParseMode::MarkdownV2 => String::from("MarkdownV2"),
|
||||
ParseMode::HTML => String::from("HTML"),
|
||||
#[allow(deprecated)]
|
||||
ParseMode::Markdown => String::from("Markdown"),
|
||||
};
|
||||
Some(FormValue::Str(string))
|
||||
|
|
|
@ -115,6 +115,7 @@ pub mod payloads {
|
|||
mod set_game_score;
|
||||
mod get_game_high_scores;
|
||||
mod get_game_high_scores_inline;
|
||||
mod set_chat_administrator_custom_title;
|
||||
|
||||
pub use {
|
||||
get_updates::{GetUpdates, AllowedUpdate},
|
||||
|
@ -189,5 +190,6 @@ pub mod payloads {
|
|||
set_game_score::SetGameScore,
|
||||
get_game_high_scores_inline::GetGameHighScoreInline,
|
||||
get_game_high_scores::GetGameHighScore,
|
||||
set_chat_administrator_custom_title::SetChatAdministratorCustomTitle,
|
||||
};
|
||||
}
|
||||
|
|
76
src/requests/payloads/set_chat_administrator_custom_title.rs
Normal file
76
src/requests/payloads/set_chat_administrator_custom_title.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
requests::{dynamic, json, Method},
|
||||
types::{True, ChatId},
|
||||
};
|
||||
|
||||
/// Use this method to set a custom title for an administrator in a supergroup
|
||||
/// promoted by the bot.
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
||||
pub struct SetChatAdministratorCustomTitle {
|
||||
/// Unique identifier for the target chat or username of the target
|
||||
/// supergroup (in the format `@supergroupusername`)
|
||||
pub chat_id: ChatId,
|
||||
|
||||
/// Unique identifier of the target user
|
||||
pub user_id: i32,
|
||||
|
||||
/// New custom title for the administrator; 0-16 characters, emoji are not
|
||||
/// allowed
|
||||
pub custom_title: String,
|
||||
}
|
||||
|
||||
impl Method for SetChatAdministratorCustomTitle {
|
||||
type Output = True;
|
||||
|
||||
const NAME: &'static str = "setChatAdministratorCustomTitle";
|
||||
}
|
||||
|
||||
impl json::Payload for SetChatAdministratorCustomTitle {}
|
||||
|
||||
impl dynamic::Payload for SetChatAdministratorCustomTitle {
|
||||
fn kind(&self) -> dynamic::Kind {
|
||||
dynamic::Kind::Json(serde_json::to_string(self).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl SetChatAdministratorCustomTitle {
|
||||
pub fn new<C, CT>(chat_id: C, user_id: i32, custom_title: CT) -> Self
|
||||
where
|
||||
C: Into<ChatId>,
|
||||
CT: Into<String>,
|
||||
{
|
||||
let chat_id = chat_id.into();
|
||||
let custom_title = custom_title.into();
|
||||
Self {
|
||||
chat_id,
|
||||
user_id,
|
||||
custom_title,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl json::Request<'_, SetChatAdministratorCustomTitle> {
|
||||
pub fn chat_id<T>(mut self, val: T) -> Self
|
||||
where
|
||||
T: Into<ChatId>,
|
||||
{
|
||||
self.payload.chat_id = val.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn user_id(mut self, val: i32) -> Self {
|
||||
self.payload.user_id = val;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn custom_title<T>(mut self, val: T) -> Self
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
self.payload.custom_title = val.into();
|
||||
self
|
||||
}
|
||||
}
|
|
@ -12,6 +12,11 @@ pub struct Animation {
|
|||
/// An identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// A video width as defined by a sender.
|
||||
pub width: u32,
|
||||
|
||||
|
@ -42,11 +47,13 @@ mod tests {
|
|||
fn deserialize() {
|
||||
let json = r#"{
|
||||
"file_id":"id",
|
||||
"file_unique_id":"",
|
||||
"width":320,
|
||||
"height":320,
|
||||
"duration":59,
|
||||
"thumb":{
|
||||
"file_id":"id",
|
||||
"file_unique_id":"",
|
||||
"width":320,
|
||||
"height":320,
|
||||
"file_size":3452
|
||||
|
@ -56,11 +63,13 @@ mod tests {
|
|||
"file_size":6500}"#;
|
||||
let expected = Animation {
|
||||
file_id: "id".to_string(),
|
||||
file_unique_id: "".to_string(),
|
||||
width: 320,
|
||||
height: 320,
|
||||
duration: 59,
|
||||
thumb: Some(PhotoSize {
|
||||
file_id: "id".to_string(),
|
||||
file_unique_id: "".to_string(),
|
||||
width: 320,
|
||||
height: 320,
|
||||
file_size: Some(3452),
|
||||
|
|
|
@ -12,6 +12,11 @@ pub struct Audio {
|
|||
/// An identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// A duration of the audio in seconds as defined by a sender.
|
||||
pub duration: u32,
|
||||
|
||||
|
@ -39,6 +44,7 @@ mod tests {
|
|||
fn deserialize() {
|
||||
let json = r#"{
|
||||
"file_id":"id",
|
||||
"file_unique_id":"",
|
||||
"duration":60,
|
||||
"performer":"Performer",
|
||||
"title":"Title",
|
||||
|
@ -46,6 +52,7 @@ mod tests {
|
|||
"file_size":123456,
|
||||
"thumb":{
|
||||
"file_id":"id",
|
||||
"file_unique_id":"",
|
||||
"width":320,
|
||||
"height":320,
|
||||
"file_size":3452
|
||||
|
@ -53,6 +60,7 @@ mod tests {
|
|||
}"#;
|
||||
let expected = Audio {
|
||||
file_id: "id".to_string(),
|
||||
file_unique_id: "".to_string(),
|
||||
duration: 60,
|
||||
performer: Some("Performer".to_string()),
|
||||
title: Some("Title".to_string()),
|
||||
|
@ -60,6 +68,7 @@ mod tests {
|
|||
file_size: Some(123_456),
|
||||
thumb: Some(PhotoSize {
|
||||
file_id: "id".to_string(),
|
||||
file_unique_id: "".to_string(),
|
||||
width: 320,
|
||||
height: 320,
|
||||
file_size: Some(3452),
|
||||
|
|
|
@ -117,6 +117,12 @@ pub enum NonPrivateChatKind {
|
|||
///
|
||||
/// [`Bot::get_chat`]: crate::Bot::get_chat
|
||||
permissions: Option<ChatPermissions>,
|
||||
|
||||
/// The minimum allowed delay between consecutive messages sent by each
|
||||
/// unpriviledged user. Returned only in [`Bot::get_chat`].
|
||||
///
|
||||
/// [`Bot::get_chat`]: crate::Bot::get_chat
|
||||
slow_mode_delay: Option<i32>,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::types::User;
|
||||
|
||||
// TODO: ChatMemberKind?...
|
||||
/// This object contains information about one member of the chat.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#chatmember).
|
||||
|
@ -13,6 +14,9 @@ pub struct ChatMember {
|
|||
/// The member's status in the chat.
|
||||
pub status: ChatMemberStatus,
|
||||
|
||||
/// Owner and administrators only. Custom title for this user
|
||||
pub custom_title: Option<String>,
|
||||
|
||||
/// Restricted and kicked only. Date when restrictions will be lifted for
|
||||
/// this user, unix time.
|
||||
pub until_date: Option<i32>,
|
||||
|
@ -123,6 +127,7 @@ mod tests {
|
|||
language_code: None,
|
||||
},
|
||||
status: ChatMemberStatus::Creator,
|
||||
custom_title: None,
|
||||
until_date: Some(123_456),
|
||||
can_be_edited: Some(true),
|
||||
can_change_info: Some(true),
|
||||
|
|
|
@ -10,8 +10,18 @@ pub struct ChatPhoto {
|
|||
/// not changed.
|
||||
pub small_file_id: String,
|
||||
|
||||
/// Unique file identifier of small (160x160) chat photo, which is supposed
|
||||
/// to be the same over time and for different bots. Can't be used to
|
||||
/// download or reuse the file.
|
||||
pub small_file_unique_id: String,
|
||||
|
||||
/// A file identifier of big (640x640) chat photo. This file_id can be used
|
||||
/// only for photo download and only for as long as the photo is not
|
||||
/// changed.
|
||||
pub big_file_id: String,
|
||||
|
||||
/// Unique file identifier of big (640x640) chat photo, which is supposed
|
||||
/// to be the same over time and for different bots. Can't be used to
|
||||
/// download or reuse the file.
|
||||
pub big_file_unique_id: String,
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@ pub struct Document {
|
|||
/// An identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// A document thumbnail as defined by a sender.
|
||||
pub thumb: Option<PhotoSize>,
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ pub struct EncryptedPassportElement {
|
|||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum EncryptedPassportElementKind {
|
||||
PersonalDetails {
|
||||
/// Base64-encoded encrypted Telegram Passport element data provided
|
||||
|
|
|
@ -13,6 +13,11 @@ pub struct File {
|
|||
/// Identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// File size, if known.
|
||||
pub file_size: u32,
|
||||
|
||||
|
|
|
@ -91,12 +91,12 @@ mod tests {
|
|||
reply_markup: Some(InlineKeyboardMarkup::new()),
|
||||
input_message_content: Some(InputMessageContent::Text {
|
||||
message_text: String::from("message_text"),
|
||||
parse_mode: Some(ParseMode::Markdown),
|
||||
parse_mode: Some(ParseMode::MarkdownV2),
|
||||
disable_web_page_preview: Some(true),
|
||||
}),
|
||||
});
|
||||
|
||||
let expected_json = r#"{"type":"audio","id":"id","audio_file_id":"audio_file_id","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"Markdown","disable_web_page_preview":true}}"#;
|
||||
let expected_json = r#"{"type":"audio","id":"id","audio_file_id":"audio_file_id","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
|
||||
let actual_json = serde_json::to_string(&structure).unwrap();
|
||||
|
||||
assert_eq!(expected_json, actual_json);
|
||||
|
|
|
@ -827,11 +827,13 @@ mod tests {
|
|||
"mime_type": "video/mp4",
|
||||
"thumb": {
|
||||
"file_id": "AAQCAAOmBAACBf2oS53pByA-I4CWWCObDwAEAQAHbQADMWcAAhYE",
|
||||
"file_unique_id":"",
|
||||
"file_size": 10339,
|
||||
"width": 256,
|
||||
"height": 320
|
||||
},
|
||||
"file_id": "BAADAgADpgQAAgX9qEud6QcgPiOAlhYE",
|
||||
"file_unique_id":"",
|
||||
"file_size": 1381334
|
||||
}
|
||||
}"#;
|
||||
|
@ -867,11 +869,13 @@ mod tests {
|
|||
"mime_type": "video/mp4",
|
||||
"thumb": {
|
||||
"file_id": "AAQCAAOmBAACBf2oS53pByA-I4CWWCObDwAEAQAHbQADMWcAAhYE",
|
||||
"file_unique_id":"",
|
||||
"file_size": 10339,
|
||||
"width": 256,
|
||||
"height": 320
|
||||
},
|
||||
"file_id": "BAADAgADpgQAAgX9qEud6QcgPiOAlhYE",
|
||||
"file_unique_id":"",
|
||||
"file_size": 1381334
|
||||
}
|
||||
}"#;
|
||||
|
@ -933,11 +937,13 @@ mod tests {
|
|||
"is_animated": true,
|
||||
"thumb": {
|
||||
"file_id": "AAQCAAMjAAOw0PgMaabKAcaXKCBLubkPAAQBAAdtAAPGKwACFgQ",
|
||||
"file_unique_id":"",
|
||||
"file_size": 4118,
|
||||
"width": 128,
|
||||
"height": 128
|
||||
},
|
||||
"file_id": "CAADAgADIwADsND4DGmmygHGlyggFgQ",
|
||||
"file_unique_id":"",
|
||||
"file_size": 16639
|
||||
}
|
||||
}"#;
|
||||
|
@ -968,18 +974,21 @@ mod tests {
|
|||
"photo": [
|
||||
{
|
||||
"file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ",
|
||||
"file_unique_id":"",
|
||||
"file_size": 18188,
|
||||
"width": 320,
|
||||
"height": 239
|
||||
},
|
||||
{
|
||||
"file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA3gAAyfcBAABFgQ",
|
||||
"file_unique_id":"",
|
||||
"file_size": 62123,
|
||||
"width": 800,
|
||||
"height": 598
|
||||
},
|
||||
{
|
||||
"file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA3kAAyTcBAABFgQ",
|
||||
"file_unique_id":"",
|
||||
"file_size": 75245,
|
||||
"width": 962,
|
||||
"height": 719
|
||||
|
|
|
@ -35,6 +35,8 @@ pub enum MessageEntityKind {
|
|||
Pre,
|
||||
TextLink { url: String },
|
||||
TextMention { user: User },
|
||||
Underline,
|
||||
Strikethrough,
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,78 +1,132 @@
|
|||
use serde::export::TryFrom;
|
||||
// see https://github.com/rust-lang/rust/issues/38832
|
||||
// (for built ins there no warnings, but for (De)Serialize, there are)
|
||||
#![allow(deprecated)]
|
||||
|
||||
use std::{str::FromStr, convert::TryFrom}
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
|
||||
/// ## Formatting options
|
||||
/// The Bot API supports basic formatting for messages.
|
||||
/// You can use **bold** and *italic* text, as well as [inline links](https://example.com)
|
||||
/// and `pre-formatted code` in your bots' messages. Telegram clients will
|
||||
/// render them accordingly. You can use either markdown-style or HTML-style
|
||||
/// The Bot API supports basic formatting for messages. You can use bold,
|
||||
/// italic, underlined and strikethrough text, as well as inline links and
|
||||
/// pre-formatted code in your bots' messages. Telegram clients will render
|
||||
/// them accordingly. You can use either markdown-style or HTML-style
|
||||
/// formatting.
|
||||
///
|
||||
/// Note that Telegram clients will display an alert to the user before opening
|
||||
/// an inline link (‘Open this link?’ together with the full URL).
|
||||
/// Note that Telegram clients will display an **alert** to the user before
|
||||
/// opening an inline link (‘Open this link?’ together with the full URL).
|
||||
///
|
||||
/// Links `tg://user?id=<user_id>` can be used to mention a user by their id
|
||||
/// Links `tg://user?id=<user_id>` can be used to mention a user by their ID
|
||||
/// without using a username. Please note:
|
||||
///
|
||||
/// - These links will work only if they are used inside an inline link. For
|
||||
/// - These links will work **only** if they are used inside an inline link. For
|
||||
/// example, they will not work, when used in an inline keyboard button or in
|
||||
/// a message text.
|
||||
/// - The mentions are only guaranteed to work if: **A**. the user is a member
|
||||
/// in the group where he was mentioned or **B**. the user has contacted the
|
||||
/// bot in the past or has sent a callback query to the bot via inline button
|
||||
/// and has not restricted linking to their account in `Settings > Privacy &
|
||||
/// Security > Forwarded Messages`.
|
||||
/// - These mentions are only guaranteed to work if the user has contacted the
|
||||
/// bot in the past, has sent a callback query to the bot via inline button or
|
||||
/// is a member in the group where he was mentioned.
|
||||
///
|
||||
/// ## Markdown style
|
||||
/// To use this mode, pass [Markdown] in the `parse_mode` field when using
|
||||
/// [SendMessage] (or other methods).
|
||||
/// ## MarkdownV2 style
|
||||
///
|
||||
/// To use this mode, pass [`MarkdownV2`] in the `parse_mode` field.
|
||||
/// Use the following syntax in your message:
|
||||
///
|
||||
/// <pre>
|
||||
/// *bold text*
|
||||
/// _italic text_
|
||||
/// ````text
|
||||
/// *bold \*text*
|
||||
/// _italic \*text_
|
||||
/// __underline__
|
||||
/// ~strikethrough~
|
||||
/// *bold _italic bold ~italic bold strikethrough~ __underline italic bold___ bold*
|
||||
/// [inline URL](http://www.example.com/)
|
||||
/// [inline mention of a user](tg://user?id=123456789)
|
||||
/// `inline fixed-width code`
|
||||
/// ```block_language
|
||||
/// `inline fixed-width code`
|
||||
/// ```
|
||||
/// pre-formatted fixed-width code block
|
||||
/// ```
|
||||
/// </pre>
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// pre-formatted fixed-width code block written in the Rust programming
|
||||
/// language ```
|
||||
/// ````
|
||||
///
|
||||
/// Please note:
|
||||
/// - Any character between 1 and 126 inclusively can be escaped anywhere with a
|
||||
/// preceding '\' character, in which case it is treated as an ordinary
|
||||
/// character and not a part of the markup.
|
||||
/// - Inside `pre` and `code` entities, all '`‘ and ’\‘ characters must be
|
||||
/// escaped with a preceding ’\' character.
|
||||
/// - Inside `(...)` part of inline link definition, all ')‘ and ’\‘ must be
|
||||
/// escaped with a preceding ’\' character.
|
||||
/// - In all other places characters ’_‘, ’*‘, ’[‘, ’]‘, ’(‘, ’)‘, ’~‘, ’`‘,
|
||||
/// ’>‘, ’#‘, ’+‘, ’+‘, ’-‘, ’|‘, ’{‘, ’}‘, ’.‘, ’!‘ must be escaped with the
|
||||
/// preceding character ’\'.
|
||||
/// - In case of ambiguity between `italic` and `underline` entities ‘__’ is
|
||||
/// always greadily treated from left to right as beginning or end of
|
||||
/// `underline` entity, so instead of `___italic underline___` use `___italic
|
||||
/// underline_\r__`, where `\r` is a character with code `13`, which will be
|
||||
/// ignored.
|
||||
///
|
||||
/// ## HTML style
|
||||
/// To use this mode, pass [HTML] in the `parse_mode` field when using
|
||||
/// [SendMessage] (or other methods).
|
||||
///
|
||||
/// To use this mode, pass [`HTML`] in the `parse_mode` field.
|
||||
/// The following tags are currently supported:
|
||||
///
|
||||
/// <pre>
|
||||
/// <b>bold</b>, <strong>bold</strong>
|
||||
/// <i>italic</i>, <em>italic</em>
|
||||
/// <a href="http://www.example.com/">inline URL</a>
|
||||
/// <a href="tg://user?id=123456789">inline mention of a user</a>
|
||||
/// <code>inline fixed-width code</code>
|
||||
/// <pre>pre-formatted fixed-width code block</pre>
|
||||
/// </pre>
|
||||
/// ````text
|
||||
/// <b>bold</b>, <strong>bold</strong>
|
||||
/// <i>italic</i>, <em>italic</em>
|
||||
/// <u>underline</u>, <ins>underline</ins>
|
||||
/// <s>strikethrough</s>, <strike>strikethrough</strike>,
|
||||
/// <del>strikethrough</del> <b>bold <i>italic bold <s>italic bold
|
||||
/// strikethrough</s> <u>underline italic bold</u></i> bold</b> <a href="http:// www.example.com/">inline URL</a>
|
||||
/// <a href="tg:// user?id=123456789">inline mention of a user</a>
|
||||
/// <code>inline fixed-width code</code>
|
||||
/// <pre>pre-formatted fixed-width code block</pre>
|
||||
/// <pre><code class="language-rust">pre-formatted fixed-width code block
|
||||
/// written in the Rust programming language</code></pre> ````
|
||||
///
|
||||
/// Please note:
|
||||
///
|
||||
/// - Only the tags mentioned above are currently supported.
|
||||
/// - Tags must not be nested.
|
||||
/// - All `<`, `>` and `&` symbols that are not a part of a tag or an HTML
|
||||
/// entity must be replaced with the corresponding HTML entities (`<` with
|
||||
/// `<`, `>` with `>` and `&` with `&`).
|
||||
/// - All numerical HTML entities are supported.
|
||||
/// - The API currently supports only the following named HTML entities: `<`,
|
||||
/// `>`, `&` and `"`.
|
||||
/// - Use nested `pre` and `code` tags, to define programming language for `pre`
|
||||
/// entity.
|
||||
/// - Programming language can't be specified for standalone `code` tags.
|
||||
///
|
||||
/// [Markdown]: crate::types::ParseMode::Markdown
|
||||
/// [HTML]: crate::types::ParseMode::HTML
|
||||
/// [SendMessage]: crate::requests::payloads::SendMessage
|
||||
/// ## Markdown style
|
||||
/// This is a legacy mode, retained for backward compatibility. To use this
|
||||
/// mode, pass [`Markdown`] in the `parse_mode` field.
|
||||
/// Use the following syntax in your message:
|
||||
/// ````text
|
||||
/// *bold text*
|
||||
/// _italic text_
|
||||
/// [inline URL](http://www.example.com/)
|
||||
/// [inline mention of a user](tg://user?id=123456789)
|
||||
/// `inline fixed-width code`
|
||||
/// ```rust
|
||||
/// pre-formatted fixed-width code block written in the Rust programming
|
||||
/// language ```
|
||||
/// ````
|
||||
///
|
||||
/// Please note:
|
||||
/// - Entities must not be nested, use parse mode [`MarkdownV2`] instead.
|
||||
/// - There is no way to specify underline and strikethrough entities, use parse
|
||||
/// mode [`MarkdownV2`] instead.
|
||||
/// - To escape characters ’_‘, ’*‘, ’`‘, ’[‘ outside of an entity, prepend the
|
||||
/// characters ’\' before them.
|
||||
/// - Escaping inside entities is not allowed, so entity must be closed first
|
||||
/// and reopened again: use `_snake_\__case_` for italic `snake_case` and
|
||||
/// `*2*\**2=4*` for bold `2*2=4`.
|
||||
///
|
||||
/// [`MarkdownV2`]: ParseMode::MarkdownV2
|
||||
/// [`HTML`]: ParseMode::HTML
|
||||
/// [`Markdown`]: ParseMode::Markdown
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub enum ParseMode {
|
||||
MarkdownV2,
|
||||
HTML,
|
||||
#[deprecated = "This is a legacy mode, retained for backward \
|
||||
compatibility. Use `MarkdownV2` instead."]
|
||||
Markdown,
|
||||
}
|
||||
|
||||
|
@ -117,6 +171,8 @@ impl FromStr for ParseMode {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(deprecated)]
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -10,6 +10,11 @@ pub struct PassportFile {
|
|||
/// Identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// File size.
|
||||
pub file_size: u64,
|
||||
|
||||
|
|
|
@ -10,6 +10,11 @@ pub struct PhotoSize {
|
|||
/// Identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// Photo width.
|
||||
pub width: i32,
|
||||
|
||||
|
@ -26,10 +31,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn deserialize() {
|
||||
let json = r#"{"file_id":"id","width":320,"height":320,
|
||||
let json = r#"{"file_id":"id","file_unique_id":"","width":320,"height":320,
|
||||
"file_size":3452}"#;
|
||||
let expected = PhotoSize {
|
||||
file_id: "id".to_string(),
|
||||
file_unique_id: "".to_string(),
|
||||
width: 320,
|
||||
height: 320,
|
||||
file_size: Some(3452),
|
||||
|
|
|
@ -11,6 +11,11 @@ pub struct Sticker {
|
|||
/// Identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// Sticker width.
|
||||
pub width: u16,
|
||||
|
||||
|
|
|
@ -11,6 +11,11 @@ pub struct Video {
|
|||
/// Identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// Video width as defined by sender.
|
||||
pub width: u32,
|
||||
|
||||
|
|
|
@ -15,6 +15,11 @@ pub struct VideoNote {
|
|||
/// Identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// Video width and height (diameter of the video message) as defined by
|
||||
/// sender.
|
||||
pub length: u32,
|
||||
|
|
|
@ -9,6 +9,11 @@ pub struct Voice {
|
|||
/// Identifier for this file.
|
||||
pub file_id: String,
|
||||
|
||||
/// Unique identifier for this file, which is supposed to be the same over
|
||||
/// time and for different bots. Can't be used to download or reuse the
|
||||
/// file.
|
||||
pub file_unique_id: String,
|
||||
|
||||
/// Duration of the audio in seconds as defined by sender.
|
||||
pub duration: u32,
|
||||
|
||||
|
|
Loading…
Reference in a new issue