use super::{RawMessage, TextMessage};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AtElement {
pub target_id: String,
pub name: Option<String>,
}
impl AtElement {
pub fn is_all(&self) -> bool {
matches!(self.target_id.as_str(), "all")
}
}
impl RawMessage for AtElement {
fn raw(&self) -> String {
format!("[at:{}]", self.target_id)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FaceElement {
pub id: u64,
}
impl RawMessage for FaceElement {
fn raw(&self) -> String {
format!("[face:{}]", self.id)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileElement {
pub file: Vec<u8>,
pub file_id: String,
pub file_size: u64,
pub file_name: String,
}
impl RawMessage for FileElement {
fn raw(&self) -> String {
format!("[file:{}]", self.file_id)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageElement {
pub file: Vec<u8>,
pub is_flash: bool,
pub summary: Option<String>,
}
impl RawMessage for ImageElement {
fn raw(&self) -> String {
format!("[image:{}]", self.summary.clone().unwrap_or(String::from("图片")))
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JsonElement {
pub data: serde_json::Value,
}
impl RawMessage for JsonElement {
fn raw(&self) -> String {
format!("[json:{}]", self.data)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoElement {
pub file: Vec<u8>,
pub file_name: String,
}
impl RawMessage for VideoElement {
fn raw(&self) -> String {
format!("[video:{}]", self.file_name)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RecordElement {
pub file: Vec<u8>,
}
impl RawMessage for RecordElement {
fn raw(&self) -> String {
format!("[record:{}]", "语音消息")
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReplyElement {
#[serde(rename = "messageId")]
pub message_id: String,
}
impl RawMessage for ReplyElement {
fn raw(&self) -> String {
format!("[reply:{}]", self.message_id)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TextElement {
pub text: String,
}
impl RawMessage for TextElement {
fn raw(&self) -> String {
format!("[text:{}]", self.text)
}
}
impl TextMessage for TextElement {
fn text(&self) -> String {
self.text.clone()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct XmlElement {
pub data: String,
}
impl RawMessage for XmlElement {
fn raw(&self) -> String {
format!("[xml:{}]", self.data)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Elements {
At(AtElement),
File(FileElement),
Image(ImageElement),
Json(JsonElement),
Record(RecordElement),
Reply(ReplyElement),
Text(TextElement),
Video(VideoElement),
Xml(XmlElement),
}
impl Elements {
pub fn as_text(&self) -> Option<&str> {
match self {
Elements::Text(text_element) => Some(&text_element.text),
_ => None,
}
}
}
impl RawMessage for Elements {
fn raw(&self) -> String {
match self {
Elements::Text(text_element) => text_element.raw(),
Elements::File(file_element) => file_element.raw(),
Elements::Image(image_element) => image_element.raw(),
Elements::Json(json_element) => json_element.raw(),
Elements::Record(record_element) => record_element.raw(),
Elements::Reply(reply_element) => reply_element.raw(),
Elements::Video(video_element) => video_element.raw(),
Elements::Xml(xml_element) => xml_element.raw(),
Elements::At(at_element) => at_element.raw(),
}
}
}
impl RawMessage for Vec<Elements> {
fn raw(&self) -> String {
self.iter().map(|element| element.raw()).collect::<Vec<_>>().join("")
}
}
#[macro_export]
macro_rules! element {
(text,$text:expr) => {
Elements::Text(TextElement { text: $text.to_string() })
};
(image,$image:expr) => {
Elements::Image(ImageElement { file: $image.into(), is_flash: false, summary: None })
};
(image,$image:expr,$is_flash:expr) => {
Elements::Image(ImageElement { file: $image.into(), is_flash: $is_flash, summary: None })
};
(image,$image:expr,$is_flash:expr,$summary:expr) => {
Elements::Image(ImageElement {
file: $image.into(),
is_flash: $is_flash,
summary: Some($summary.to_string()),
})
};
(at,$target_id:expr) => {
Elements::At(AtElement { target_id: $target_id.to_string(), name: None })
};
(at_all) => {
Elements::At(AtElement {
target_id: "all".to_string(), name: Some("全体成员".to_string())
})
};
(face,$id:expr) => {
Elements::Face(FaceElement { id: $id })
};
(reply,$message_id:expr) => {
Elements::Reply(ReplyElement { message_id: $message_id.to_string() })
};
(record,$record:expr) => {
Elements::Record(RecordElement { file: $record.into() })
};
(file,$file:expr,$file_id:expr,$file_size:expr,$file_name:expr) => {
Elements::File(FileElement {
file: $file.into(),
file_id: $file_id.to_string(),
file_size: $file_size,
file_name: $file_name.to_string(),
})
};
(video,$video:expr,$video_name:expr) => {
Elements::Video(VideoElement { file: $video.into(), file_name: $video_name.to_string() })
};
(json,$data:expr) => {
Elements::Json(JsonElement { data: serde_json::Value::String($data.to_string()) })
};
(xml,$data:expr) => {
Elements::Xml(XmlElement { data: String::from($data) })
};
}