Added Message

This commit is contained in:
Mr-Andersen 2019-09-07 14:58:47 +03:00
parent 05899b53d2
commit 5bfe47927d
3 changed files with 191 additions and 39 deletions

View file

@ -1,18 +1,18 @@
use crate::core::types::{ChatPermissions, ChatPhoto, Message}; use crate::core::types::{ChatPermissions, ChatPhoto, Message};
#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Debug, Deserialize, Eq, Hash, PartialEq)]
pub struct Chat { pub struct Chat {
#[serde(rename = "chat_id")] #[serde(rename = "chat_id")]
pub id: i32, pub id: i64,
#[serde(flatten)] #[serde(flatten)]
pub type_: ChatType, pub chat_kind: ChatKind,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub photo: Option<ChatPhoto>, pub photo: Option<ChatPhoto>,
} }
struct PrivateChatTypeVisitor; struct PrivateChatKindVisitor;
impl<'de> serde::de::Visitor<'de> for PrivateChatTypeVisitor { impl<'de> serde::de::Visitor<'de> for PrivateChatKindVisitor {
type Value = (); type Value = ();
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
@ -36,51 +36,43 @@ impl<'de> serde::de::Visitor<'de> for PrivateChatTypeVisitor {
fn assert_private_field<'de, D: serde::Deserializer<'de>>( fn assert_private_field<'de, D: serde::Deserializer<'de>>(
des: D, des: D,
) -> Result<(), D::Error> { ) -> Result<(), D::Error> {
des.deserialize_str(PrivateChatTypeVisitor) des.deserialize_str(PrivateChatKindVisitor)
} }
fn serialize_private_field<S: serde::Serializer>( /*fn serialize_private_field<S: serde::Serializer>(
_: &(), _: &(),
ser: S, ser: S,
) -> Result<S::Ok, S::Error> { ) -> Result<S::Ok, S::Error> {
ser.serialize_str("private") ser.serialize_str("private")
} }*/
#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Debug, Deserialize, Eq, Hash, PartialEq)]
#[serde(rename_all = "snake_case")]
#[serde(untagged)] #[serde(untagged)]
pub enum ChatType { pub enum ChatKind {
NotPrivate { NonPrivate {
#[serde(skip_serializing_if = "Option::is_none")]
title: Option<String>, title: Option<String>,
#[serde(flatten)] #[serde(flatten)]
type_: NotPrivateChatType, non_private_chat_kind: NonPrivateChatKind,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>, description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
invite_link: Option<String>, invite_link: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pinned_message: Option<Box<Message>>, pinned_message: Option<Box<Message>>,
}, },
Private { Private {
/// Dummy field. Used to ensure that "type" field is equal to "private" /// Dummy field. Used to ensure that "type" field is equal to "private"
#[serde(rename = "type")] #[serde(rename = "type")]
#[serde(deserialize_with = "assert_private_field")] #[serde(deserialize_with = "assert_private_field")]
#[serde(serialize_with = "serialize_private_field")] // #[serde(serialize_with = "serialize_private_field")]
type_: (), type_: (),
#[serde(skip_serializing_if = "Option::is_none")]
username: Option<String>, username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
first_name: Option<String>, first_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
last_name: Option<String>, last_name: Option<String>,
}, },
} }
#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Debug, Deserialize, Eq, Hash, PartialEq)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum NotPrivateChatType { pub enum NonPrivateChatKind {
Channel { Channel {
username: Option<String>, username: Option<String>,
}, },
@ -98,16 +90,16 @@ pub enum NotPrivateChatType {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::core::types::*; use crate::core::types::*;
use serde_json::{from_str, to_string}; use serde_json::from_str;
#[test] #[test]
fn channel_de() { fn channel_de() {
assert_eq!( assert_eq!(
Chat { Chat {
id: -1, id: -1,
type_: ChatType::NotPrivate { chat_kind: ChatKind::NonPrivate {
title: None, title: None,
type_: NotPrivateChatType::Channel { non_private_chat_kind: NonPrivateChatKind::Channel {
username: Some("channelname".into()) username: Some("channelname".into())
}, },
description: None, description: None,
@ -128,7 +120,7 @@ mod tests {
assert_eq!( assert_eq!(
Chat { Chat {
id: 0, id: 0,
type_: ChatType::Private { chat_kind: ChatKind::Private {
type_: (), type_: (),
username: Some("username".into()), username: Some("username".into()),
first_name: Some("Anon".into()), first_name: Some("Anon".into()),
@ -146,12 +138,12 @@ mod tests {
assert!(from_str::<Chat>(r#"{"chat_id":0,"type":"WRONG"}"#).is_err()); assert!(from_str::<Chat>(r#"{"chat_id":0,"type":"WRONG"}"#).is_err());
} }
#[test] /*#[test]
fn private_chat_ser() { fn private_chat_ser() {
assert_eq!( assert_eq!(
to_string(&Chat { to_string(&Chat {
id: 0, id: 0,
type_: ChatType::Private { type_: ChatKind::Private {
type_: (), type_: (),
username: None, username: None,
first_name: None, first_name: None,
@ -162,5 +154,5 @@ mod tests {
.unwrap(), .unwrap(),
r#"{"chat_id":0,"type":"private"}"#.to_owned() r#"{"chat_id":0,"type":"private"}"#.to_owned()
); );
} }*/
} }

View file

@ -4,17 +4,177 @@ use crate::core::types::{
SuccessfulPayment, User, Venue, Video, VideoNote, Voice, SuccessfulPayment, User, Venue, Video, VideoNote, Voice,
}; };
#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Debug, Deserialize, Eq, Hash, PartialEq)]
pub struct Message { pub struct Message {
#[serde(rename = "message_id")] #[serde(rename = "message_id")]
pub id: i32, pub id: i64,
pub date: i32, pub date: i32,
pub chat: Chat, pub chat: Box<Chat>,
#[serde(flatten)] #[serde(flatten)]
pub type_: MessageType, pub message_kind: MessageKind,
} }
#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Debug, Deserialize, Eq, Hash, PartialEq)]
#[serde(rename_all = "snake_case")]
#[serde(untagged)] #[serde(untagged)]
pub enum MessageType {} pub enum MessageKind {
IncomingMessage {
#[serde(flatten)]
forward_kind: ForwardKind,
edit_date: Option<i32>,
#[serde(flatten)]
media_kind: MediaKind,
reply_markup: Option<InlineKeyboardMarkup>,
},
NewChatMembers {
new_chat_members: Vec<User>,
},
LeftChatMember {
left_chat_member: User,
},
NewChatTitle {
new_chat_title: String,
},
NewChatPhoto {
new_chat_photo: Vec<PhotoSize>,
},
DeleteChatPhoto {
delete_chat_photo: bool,
},
GroupChatCreated {
group_chat_created: bool,
},
SupergroupChatCreated {
supergroup_chat_created: bool,
},
ChannelChatCreated {
channel_chat_created: bool,
},
Migrate {
migrate_to_chat_id: i64,
migrate_from_chat_id: i64,
},
PinnedMessage {
pinned_message: Box<Message>,
},
Invoice {
invoice: Invoice,
},
SuccessfulPayment {
successful_payment: SuccessfulPayment,
},
ConnectedWebsite {
connected_website: String,
},
PassportData {
passport_data: PassportData,
},
}
#[derive(Debug, Deserialize, Eq, Hash, PartialEq)]
#[serde(untagged)]
pub enum ForwardKind {
ChannelForward {
forward_from_channel: Box<Chat>,
forward_from_message_id: i64,
forward_signature: String,
},
NonChannelForward {
#[serde(flatten)]
forward: UserOrSenderName,
},
Origin {
reply_to_message: Option<Box<Message>>,
},
}
#[derive(Debug, Deserialize, Eq, Hash, PartialEq)]
#[serde(untagged)]
pub enum UserOrSenderName {
User { from: User },
SenderName { sender_name: String },
}
#[derive(Debug, Deserialize, Eq, Hash, PartialEq)]
#[serde(untagged)]
pub enum MediaKind {
Animation {
animation: Animation,
caption: Option<String>,
},
Audio {
audio: Audio,
caption: Option<String>,
},
Contact {
contact: Contact,
},
Document {
document: Document,
caption: Option<String>,
},
Game {
game: Game,
},
Location {
location: Location,
},
Photo {
sizes: Vec<PhotoSize>,
caption: Option<String>,
},
Poll {
poll: Poll,
},
Sticker {
sticker: Sticker,
},
Text {
text: String,
entities: Vec<MessageEntity>,
},
Video {
video: Video,
caption: Option<String>,
},
VideoNote {
video_note: VideoNote,
},
Voice {
voice: Voice,
caption: Option<String>,
},
Venue {
venue: Venue,
},
}
#[cfg(test)]
mod tests {
use crate::core::types::*;
use serde_json::from_str;
#[test]
fn incoming_origin_de() {
assert_eq!(Message {
id: 0,
date: 0,
chat: Box::new(Chat {
id: 0,
chat_kind: ChatKind::Private {
type_: (),
username: None,
first_name: None,
last_name: None
},
photo: None
}),
message_kind: MessageKind::IncomingMessage {
forward_kind: ForwardKind::Origin { reply_to_message: None },
edit_date: None,
media_kind: MediaKind::Text { text: "Hello".to_string(), entities: vec![] },
reply_markup: None
}
},
from_str(r#"{"message_id":0,"date":0,"chat":{"chat_id":0,"type":"private"},"text":"Hello","entities":[]}"#).unwrap());
}
}

View file

@ -4,7 +4,7 @@ pub use self::{
answer_pre_checkout_query::AnswerPreCheckoutQuery, answer_pre_checkout_query::AnswerPreCheckoutQuery,
answer_shipping_query::AnswerShippingQuery, answer_shipping_query::AnswerShippingQuery,
audio::Audio, audio::Audio,
chat::{Chat, ChatType, NotPrivateChatType}, chat::{Chat, ChatKind, NonPrivateChatKind},
chat_member::ChatMember, chat_member::ChatMember,
chat_permissions::ChatPermissions, chat_permissions::ChatPermissions,
chat_photo::ChatPhoto, chat_photo::ChatPhoto,
@ -13,7 +13,7 @@ pub use self::{
input_media::InputMedia, input_media::InputMedia,
invoice::Invoice, invoice::Invoice,
label_price::LabeledPrice, label_price::LabeledPrice,
message::Message, message::{ForwardKind, MediaKind, Message, MessageKind, UserOrSenderName},
message_entity::MessageEntity, message_entity::MessageEntity,
order_info::OrderInfo, order_info::OrderInfo,
parse_mode::ParseMode, parse_mode::ParseMode,