1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use crate::utils::text_decorations::{add_surrogates, remove_surrogates};
use super::User;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
/// This object represents one special entity in a text message. For example, hashtags, usernames, URLs, etc.
/// # Documentation
/// <https://core.telegram.org/bots/api#messageentity>
#[skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct MessageEntity {
/// Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag`), 'cashtag' (:code:`$USD`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users [`without usernames`](https://telegram.org/blog/edit#new-mentions)), 'custom_emoji' (for inline custom emoji stickers)
#[serde(rename = "type")]
pub entity_type: String,
/// Offset in UTF-16 code units to the start of the entity
pub offset: i64,
/// Length of the entity in UTF-16 code units
pub length: i64,
/// For 'text_link' only, URL that will be opened after user taps on the text
pub url: Option<String>,
/// For 'text_mention' only, the mentioned user
pub user: Option<User>,
/// For 'pre' only, the programming language of the entity text
pub language: Option<String>,
/// For 'custom_emoji' only, unique identifier of the custom emoji. Use [`GetCustomEmojiStickers`](crate::methods::GetCustomEmojiStickers) to get full information about the sticker
pub custom_emoji_id: Option<String>,
}
impl MessageEntity {
#[must_use]
pub fn new(entity_type: impl Into<String>, offset: i64, length: i64) -> Self {
Self {
entity_type: entity_type.into(),
offset,
length,
url: None,
user: None,
language: None,
custom_emoji_id: None,
}
}
#[must_use]
pub fn offset(self, val: i64) -> Self {
Self {
offset: val,
..self
}
}
#[must_use]
pub fn length(self, val: i64) -> Self {
Self {
length: val,
..self
}
}
#[must_use]
pub fn url(self, val: impl Into<String>) -> Self {
Self {
url: Some(val.into()),
..self
}
}
#[must_use]
pub fn user(self, val: User) -> Self {
Self {
user: Some(val),
..self
}
}
#[must_use]
pub fn language(self, val: impl Into<String>) -> Self {
Self {
language: Some(val.into()),
..self
}
}
#[must_use]
pub fn custom_emoji_id(self, val: impl Into<String>) -> Self {
Self {
custom_emoji_id: Some(val.into()),
..self
}
}
}
impl MessageEntity {
/// # Panics
/// If the `self.offset` or `self.offset + self.length` is out of the range
#[must_use]
pub fn extract_from(&self, text: &str) -> String {
let with_surrogates = add_surrogates(
&text[usize::try_from(self.offset).unwrap() * 2
..usize::try_from(self.offset + self.length).unwrap() * 2],
);
remove_surrogates(&with_surrogates)
}
}