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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
use std::{error::Error, fmt};
use serde::{Deserialize, Serialize};
use serde_json::Error as JsonError;
use crate::types::{ChatId, Integer, ParseMode, TextEntities, TextEntity};
#[cfg(test)]
mod tests;
/// Describes reply parameters for the message that is being sent.
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct ReplyParameters {
message_id: Integer,
#[serde(skip_serializing_if = "Option::is_none")]
allow_sending_without_reply: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
chat_id: Option<ChatId>,
#[serde(flatten, skip_serializing_if = "Option::is_none")]
quote: Option<ReplyQuote>,
}
impl ReplyParameters {
/// Creates a new `ReplyParameters`.
///
/// # Arguments
///
/// * `message_id` - Identifier of the message that will be replied to in the current chat,
/// or in the chat chat_id if it is specified.
pub fn new(message_id: Integer) -> Self {
Self {
message_id,
allow_sending_without_reply: None,
chat_id: None,
quote: None,
}
}
/// Sets a new value for an `allow_sending_without_reply` flag.
///
/// # Arguments
///
/// * `value` - Whether the message should be sent even if the specified message to be replied to is not found.
///
/// Can be used only for replies in the same chat and forum topic.
pub fn with_allow_sending_without_reply(mut self, value: bool) -> Self {
self.allow_sending_without_reply = Some(value);
self
}
/// Sets a new chat ID.
///
/// # Arguments
///
/// * `value` - If the message to be replied to is from a different chat, unique identifier for the chat.
pub fn with_chat_id<T>(mut self, value: T) -> Self
where
T: Into<ChatId>,
{
self.chat_id = Some(value.into());
self
}
/// Sets a new quote.
///
/// # Arguments
///
/// * `value` - Quoted part of the message to be replied to.
pub fn with_quote(mut self, value: ReplyQuote) -> Self {
self.quote = Some(value);
self
}
pub(crate) fn serialize(&self) -> Result<String, ReplyParametersError> {
serde_json::to_string(self).map_err(ReplyParametersError::Serialize)
}
}
/// Quoted part of the message to be replied to.
///
/// The text must contain 0-1024 characters after entities parsing.
/// The quote must be an exact substring of the message to be replied to,
/// including bold, italic, underline, strikethrough, spoiler, and custom_emoji entities.
/// The message will fail to send if the quote isn't found in the original message.
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct ReplyQuote {
#[serde(rename = "quote_position")]
position: Integer,
#[serde(rename = "quote")]
text: String,
#[serde(rename = "quote_entities", skip_serializing_if = "Option::is_none")]
entities: Option<TextEntities>,
#[serde(rename = "quote_parse_mode", skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>,
}
impl ReplyQuote {
/// Creates a new `ReplyQuote`.
///
/// # Arguments
///
/// * `position` - Position of the quote in the original message in UTF-16 code units.
/// * `text` - Quoted part of the message to be replied to.
pub fn new<T>(position: Integer, text: T) -> Self
where
T: Into<String>,
{
Self {
position,
text: text.into(),
entities: None,
parse_mode: None,
}
}
/// Sets a new list of entities.
///
/// # Arguments
///
/// * `value` - A list of special entities that appear in the quote.
///
/// It can be specified instead of parse mode.
pub fn with_entities<T>(mut self, value: T) -> Self
where
T: IntoIterator<Item = TextEntity>,
{
self.entities = Some(value.into_iter().collect());
self.parse_mode = None;
self
}
/// Sets a new parse mode.
///
/// # Arguments
///
/// * `value` - Mode for parsing entities in the quote.
///
/// It can be specified instead of entities.
pub fn with_parse_mode(mut self, value: ParseMode) -> Self {
self.parse_mode = Some(value);
self.entities = None;
self
}
}
/// Represents an error occurred with reply markup.
#[derive(Debug)]
pub enum ReplyParametersError {
/// Can not serialize markup
Serialize(JsonError),
}
impl Error for ReplyParametersError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
ReplyParametersError::Serialize(err) => Some(err),
}
}
}
impl fmt::Display for ReplyParametersError {
fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
match self {
ReplyParametersError::Serialize(err) => write!(out, "can not serialize reply parameters: {}", err),
}
}
}