use serde::{Deserialize, Serialize};
use crate::chat::Location;
use crate::file::{
Animation, Audio, InputMediaAnimation, InputMediaAudio, InputMediaPhoto, InputMediaVideo,
InputMediaVoiceNote, PhotoSize, Video, Voice,
};
use crate::user::User;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum RichText {
Plain(String),
Array(Vec<RichText>),
Node(Box<RichTextNode>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum RichTextNode {
Bold(RichTextBold),
Italic(RichTextItalic),
Underline(RichTextUnderline),
Strikethrough(RichTextStrikethrough),
Spoiler(RichTextSpoiler),
DateTime(RichTextDateTime),
TextMention(RichTextTextMention),
Subscript(RichTextSubscript),
Superscript(RichTextSuperscript),
Marked(RichTextMarked),
Code(RichTextCode),
CustomEmoji(RichTextCustomEmoji),
MathematicalExpression(RichTextMathematicalExpression),
Url(RichTextUrl),
EmailAddress(RichTextEmailAddress),
PhoneNumber(RichTextPhoneNumber),
BankCardNumber(RichTextBankCardNumber),
Mention(RichTextMention),
Hashtag(RichTextHashtag),
Cashtag(RichTextCashtag),
BotCommand(RichTextBotCommand),
Anchor(RichTextAnchor),
AnchorLink(RichTextAnchorLink),
Reference(RichTextReference),
ReferenceLink(RichTextReferenceLink),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextBold {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextItalic {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextUnderline {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextStrikethrough {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextSpoiler {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextDateTime {
pub text: RichText,
pub unix_time: i64,
pub date_time_format: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextTextMention {
pub text: RichText,
pub user: User,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextSubscript {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextSuperscript {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextMarked {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextCode {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextCustomEmoji {
pub custom_emoji_id: String,
pub alternative_text: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextMathematicalExpression {
pub expression: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextUrl {
pub text: RichText,
pub url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextEmailAddress {
pub text: RichText,
pub email_address: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextPhoneNumber {
pub text: RichText,
pub phone_number: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextBankCardNumber {
pub text: RichText,
pub bank_card_number: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextMention {
pub text: RichText,
pub username: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextHashtag {
pub text: RichText,
pub hashtag: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextCashtag {
pub text: RichText,
pub cashtag: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextBotCommand {
pub text: RichText,
pub bot_command: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextAnchor {
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextAnchorLink {
pub text: RichText,
pub anchor_name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextReferenceLink {
pub text: RichText,
pub reference_name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextReference {
pub text: RichText,
#[serde(rename = "name")]
pub footnote_name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockCaption {
pub text: RichText,
#[serde(skip_serializing_if = "Option::is_none")]
pub credit: Option<RichText>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockTableCell {
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<RichText>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_header: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub colspan: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rowspan: Option<u32>,
pub align: String,
pub valign: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockListItem {
pub label: String,
pub blocks: Vec<RichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_checkbox: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_checked: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<i64>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum RichBlock {
Paragraph(RichBlockParagraph),
#[serde(rename = "heading")]
SectionHeading(RichBlockSectionHeading),
Pre(RichBlockPreformatted),
Footer(RichBlockFooter),
Divider(RichBlockDivider),
MathematicalExpression(RichBlockMathematicalExpression),
Anchor(RichBlockAnchor),
List(RichBlockList),
Blockquote(RichBlockBlockQuotation),
Pullquote(RichBlockPullQuotation),
Collage(RichBlockCollage),
Slideshow(RichBlockSlideshow),
Table(RichBlockTable),
Details(RichBlockDetails),
Map(RichBlockMap),
Animation(RichBlockAnimation),
Audio(RichBlockAudio),
Photo(RichBlockPhoto),
Video(RichBlockVideo),
VoiceNote(RichBlockVoiceNote),
Thinking(RichBlockThinking),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockParagraph {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockSectionHeading {
pub text: RichText,
pub size: u8,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockPreformatted {
pub text: RichText,
#[serde(skip_serializing_if = "Option::is_none")]
pub language: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockFooter {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockDivider {}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockMathematicalExpression {
pub expression: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockAnchor {
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockList {
pub items: Vec<RichBlockListItem>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockBlockQuotation {
pub blocks: Vec<RichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub credit: Option<RichText>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockPullQuotation {
pub text: RichText,
#[serde(skip_serializing_if = "Option::is_none")]
pub credit: Option<RichText>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockCollage {
pub blocks: Vec<RichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockSlideshow {
pub blocks: Vec<RichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockTable {
pub cells: Vec<Vec<RichBlockTableCell>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_bordered: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_striped: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichText>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockDetails {
pub summary: RichText,
pub blocks: Vec<RichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_open: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockMap {
pub location: crate::chat::Location,
pub zoom: u8,
pub width: u32,
pub height: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockAnimation {
pub animation: Animation,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_spoiler: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockAudio {
pub audio: Audio,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockPhoto {
pub photo: Vec<PhotoSize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_spoiler: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockVideo {
pub video: Video,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_spoiler: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockVoiceNote {
pub voice_note: Voice,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichBlockThinking {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichMessage {
pub blocks: Vec<RichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_rtl: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockListItem {
pub blocks: Vec<InputRichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_checkbox: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_checked: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<i64>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum InputRichBlock {
Paragraph(InputRichBlockParagraph),
#[serde(rename = "heading")]
SectionHeading(InputRichBlockSectionHeading),
#[serde(rename = "pre")]
Preformatted(InputRichBlockPreformatted),
Footer(InputRichBlockFooter),
Divider(InputRichBlockDivider),
MathematicalExpression(InputRichBlockMathematicalExpression),
Anchor(InputRichBlockAnchor),
List(InputRichBlockList),
#[serde(rename = "blockquote")]
BlockQuotation(InputRichBlockBlockQuotation),
#[serde(rename = "pullquote")]
PullQuotation(InputRichBlockPullQuotation),
Collage(InputRichBlockCollage),
Slideshow(InputRichBlockSlideshow),
Table(InputRichBlockTable),
Details(InputRichBlockDetails),
Map(InputRichBlockMap),
Animation(InputRichBlockAnimation),
Audio(InputRichBlockAudio),
Photo(InputRichBlockPhoto),
Video(InputRichBlockVideo),
VoiceNote(InputRichBlockVoiceNote),
Thinking(InputRichBlockThinking),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockParagraph {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockSectionHeading {
pub text: RichText,
pub size: u8,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockPreformatted {
pub text: RichText,
#[serde(skip_serializing_if = "Option::is_none")]
pub language: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockFooter {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct InputRichBlockDivider {}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockMathematicalExpression {
pub expression: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockAnchor {
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockList {
pub items: Vec<InputRichBlockListItem>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockBlockQuotation {
pub blocks: Vec<InputRichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub credit: Option<RichText>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockPullQuotation {
pub text: RichText,
#[serde(skip_serializing_if = "Option::is_none")]
pub credit: Option<RichText>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockCollage {
pub blocks: Vec<InputRichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockSlideshow {
pub blocks: Vec<InputRichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockTable {
pub cells: Vec<Vec<RichBlockTableCell>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_bordered: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_striped: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichText>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockDetails {
pub summary: RichText,
pub blocks: Vec<InputRichBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_open: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockMap {
pub location: Location,
pub zoom: u8,
pub width: u32,
pub height: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockAnimation {
pub animation: InputMediaAnimation,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockAudio {
pub audio: InputMediaAudio,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockPhoto {
pub photo: InputMediaPhoto,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockVideo {
pub video: InputMediaVideo,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockVoiceNote {
pub voice_note: InputMediaVoiceNote,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<RichBlockCaption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichBlockThinking {
pub text: RichText,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum InputRichMessageMediaKind {
Animation(InputMediaAnimation),
Audio(InputMediaAudio),
Photo(InputMediaPhoto),
Video(InputMediaVideo),
VoiceNote(InputMediaVoiceNote),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichMessageMedia {
pub id: String,
pub media: InputRichMessageMediaKind,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichMessage {
#[serde(skip_serializing_if = "Option::is_none")]
pub html: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub markdown: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub blocks: Option<Vec<InputRichBlock>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub media: Option<Vec<InputRichMessageMedia>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_rtl: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub skip_entity_detection: Option<bool>,
}
impl InputRichMessage {
pub fn from_html(html: impl Into<String>) -> Self {
Self {
html: Some(html.into()),
markdown: None,
blocks: None,
media: None,
is_rtl: None,
skip_entity_detection: None,
}
}
pub fn from_markdown(markdown: impl Into<String>) -> Self {
Self {
html: None,
markdown: Some(markdown.into()),
blocks: None,
media: None,
is_rtl: None,
skip_entity_detection: None,
}
}
pub fn from_blocks(blocks: Vec<InputRichBlock>) -> Self {
Self {
html: None,
markdown: None,
blocks: Some(blocks),
media: None,
is_rtl: None,
skip_entity_detection: None,
}
}
#[must_use]
pub fn media(mut self, media: Vec<InputRichMessageMedia>) -> Self {
self.media = Some(media);
self
}
#[must_use]
pub fn rtl(mut self, v: bool) -> Self {
self.is_rtl = Some(v);
self
}
#[must_use]
pub fn skip_entity_detection(mut self, v: bool) -> Self {
self.skip_entity_detection = Some(v);
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputRichMessageContent {
pub rich_message: InputRichMessage,
}