use crate::models::serde_helpers::{is_zero_u32, option_is_none_or_default};
use base64::Engine;
use serde::{Deserialize, Serialize};
use super::{
ActionButton, Ark, Embed, InputNotify, Keyboard, KeyboardPayload, MarkdownPayload, Media,
MediaInfo, MessageCreateType, MessageToCreate, PromptKeyboard, Reference, Stream,
option_message_type_is_none_or_zero,
};
macro_rules! channel_like_message_params_struct {
(
$(#[$meta:meta])*
pub struct $name:ident;
) => {
$(#[$meta])*
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct $name {
/// Message content
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub content: Option<String>,
#[serde(skip_serializing_if = "option_message_type_is_none_or_zero")]
pub msg_type: Option<MessageCreateType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub embed: Option<Embed>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ark: Option<Ark>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message_reference: Option<Reference>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub image: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_image: Option<String>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub msg_id: Option<String>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub event_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub markdown: Option<MarkdownPayload>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keyboard: Option<Keyboard>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub timestamp: Option<i64>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub msg_seq: Option<u32>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub subscribe_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub input_notify: Option<InputNotify>,
#[serde(skip_serializing_if = "Option::is_none")]
pub media: Option<MediaInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_keyboard: Option<PromptKeyboard>,
#[serde(skip_serializing_if = "Option::is_none")]
pub action_button: Option<ActionButton>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<Stream>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub feature_id: Option<u32>,
}
};
}
macro_rules! open_message_params_struct {
(
$(#[$meta:meta])*
pub struct $name:ident;
) => {
$(#[$meta])*
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct $name {
/// Message type (0=text, 1=rich text, 2=markdown, 3=ark, 4=embed, 7=media)
#[serde(skip_serializing_if = "is_zero_u32")]
pub msg_type: u32,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub embed: Option<Embed>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ark: Option<Ark>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message_reference: Option<Reference>,
#[serde(skip_serializing_if = "Option::is_none")]
pub media: Option<Media>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub msg_id: Option<String>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub msg_seq: Option<u32>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub event_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub markdown: Option<MarkdownPayload>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keyboard: Option<KeyboardPayload>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub timestamp: Option<i64>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub subscribe_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub input_notify: Option<InputNotify>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_keyboard: Option<PromptKeyboard>,
#[serde(skip_serializing_if = "Option::is_none")]
pub action_button: Option<ActionButton>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<Stream>,
#[serde(skip_serializing_if = "option_is_none_or_default")]
pub feature_id: Option<u32>,
}
};
}
channel_like_message_params_struct! {
pub struct MessageParams;
}
open_message_params_struct! {
pub struct GroupMessageParams;
}
open_message_params_struct! {
pub struct C2CMessageParams;
}
channel_like_message_params_struct! {
pub struct DirectMessageParams;
}
macro_rules! impl_channel_like_message_params {
($name:ident) => {
impl $name {
pub fn new_text(content: impl Into<String>) -> Self {
Self {
content: Some(content.into()),
..Default::default()
}
}
pub fn with_file_image(mut self, data: &[u8]) -> Self {
self.file_image = Some(base64::engine::general_purpose::STANDARD.encode(data));
self
}
pub fn with_reply(mut self, message_id: impl Into<String>) -> Self {
self.msg_id = Some(message_id.into());
self
}
pub fn into_message_to_create(self) -> MessageToCreate {
self.into()
}
}
impl From<$name> for MessageToCreate {
fn from(params: $name) -> Self {
Self {
content: params.content,
msg_type: params.msg_type,
embed: params.embed,
ark: params.ark,
image: params.image,
msg_id: params.msg_id,
message_reference: params.message_reference,
markdown: params.markdown,
keyboard: params.keyboard,
event_id: params.event_id,
timestamp: params.timestamp,
msg_seq: params.msg_seq,
subscribe_id: params.subscribe_id,
input_notify: params.input_notify,
media: params.media,
prompt_keyboard: params.prompt_keyboard,
action_button: params.action_button,
stream: params.stream,
feature_id: params.feature_id,
file_image: params.file_image,
}
}
}
};
}
macro_rules! impl_open_message_params {
($name:ident) => {
impl $name {
pub fn new_text(content: impl Into<String>) -> Self {
Self {
msg_type: 0,
content: Some(content.into()),
..Default::default()
}
}
pub fn with_reply(mut self, message_id: impl Into<String>) -> Self {
self.msg_id = Some(message_id.into());
self
}
pub fn into_message_to_create(self) -> MessageToCreate {
self.into()
}
}
impl From<$name> for MessageToCreate {
fn from(params: $name) -> Self {
Self {
content: params.content,
msg_type: Some(MessageCreateType::from(params.msg_type)),
embed: params.embed,
ark: params.ark,
msg_id: params.msg_id,
message_reference: params.message_reference,
markdown: params.markdown,
keyboard: params.keyboard.map(Into::into),
event_id: params.event_id,
timestamp: params.timestamp,
msg_seq: params.msg_seq,
subscribe_id: params.subscribe_id,
input_notify: params.input_notify,
media: params.media.map(Into::into),
prompt_keyboard: params.prompt_keyboard,
action_button: params.action_button,
stream: params.stream,
feature_id: params.feature_id,
..Default::default()
}
}
}
};
}
impl_channel_like_message_params!(MessageParams);
impl_open_message_params!(GroupMessageParams);
impl_open_message_params!(C2CMessageParams);
impl_channel_like_message_params!(DirectMessageParams);