use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(tag = "type", content = "data")]
pub enum MessageElement {
#[serde(rename = "text")]
Text {
#[serde(rename = "content")]
text: String,
},
#[serde(rename = "at")]
At {
id: String,
name: Option<String>,
role: Option<String>,
#[serde(rename = "type")]
at_type: Option<String>, },
#[serde(rename = "sharp")]
Sharp {
id: String,
name: Option<String>,
},
#[serde(rename = "img")]
Image {
src: String,
title: Option<String>,
width: Option<u32>,
height: Option<u32>,
cache: Option<bool>,
timeout: Option<String>,
},
#[serde(rename = "audio")]
Audio {
src: String,
title: Option<String>,
duration: Option<u64>,
poster: Option<String>,
cache: Option<bool>,
timeout: Option<String>,
},
#[serde(rename = "video")]
Video {
src: String,
title: Option<String>,
duration: Option<u64>,
poster: Option<String>,
width: Option<u32>,
height: Option<u32>,
cache: Option<bool>,
timeout: Option<String>,
},
#[serde(rename = "file")]
File {
src: String,
name: Option<String>,
poster: Option<String>,
cache: Option<bool>,
timeout: Option<String>,
},
#[serde(rename = "quote")]
Quote {
id: String,
forward: Option<bool>,
children: Vec<MessageElement>,
},
#[serde(rename = "author")]
Author {
id: String,
name: Option<String>,
avatar: Option<String>,
},
#[serde(rename = "message")]
Message {
id: Option<String>,
forward: Option<bool>,
children: Vec<MessageElement>,
},
#[serde(rename = "strong")]
Bold { children: Vec<MessageElement> },
#[serde(rename = "em")]
Italic { children: Vec<MessageElement> },
#[serde(rename = "u")]
Underline { children: Vec<MessageElement> },
#[serde(rename = "s")]
Strikethrough { children: Vec<MessageElement> },
#[serde(rename = "spl")]
Spoiler { children: Vec<MessageElement> },
#[serde(rename = "code")]
Code { children: Vec<MessageElement> },
#[serde(rename = "sup")]
Superscript { children: Vec<MessageElement> },
#[serde(rename = "sub")]
Subscript { children: Vec<MessageElement> },
#[serde(rename = "br")]
LineBreak,
#[serde(rename = "p")]
Paragraph { children: Vec<MessageElement> },
#[serde(rename = "a")]
Link {
href: String,
children: Vec<MessageElement>,
},
#[serde(rename = "li")]
ListItem { children: Vec<MessageElement> },
#[serde(rename = "ul")]
UnorderedList { children: Vec<MessageElement> },
#[serde(rename = "ol")]
OrderedList {
start: Option<u64>,
reversed: Option<bool>,
#[serde(rename = "type")]
list_type: Option<String>, children: Vec<MessageElement>,
},
#[serde(rename = "table")]
Table { children: Vec<MessageElement> }, #[serde(rename = "thead")]
TableHead { children: Vec<MessageElement> }, #[serde(rename = "tbody")]
TableBody { children: Vec<MessageElement> }, #[serde(rename = "tfoot")]
TableFoot { children: Vec<MessageElement> }, #[serde(rename = "tr")]
TableRow { children: Vec<MessageElement> }, #[serde(rename = "th")]
TableHeader { children: Vec<MessageElement> },
#[serde(rename = "td")]
TableCell { children: Vec<MessageElement> },
#[serde(rename = "button")]
Button {
id: Option<String>,
theme: Option<String>, href: Option<String>,
text: Option<String>,
disabled: Option<bool>,
children: Vec<MessageElement>,
},
#[serde(rename = "span")]
Span {
style: Option<String>,
children: Vec<MessageElement>,
},
#[serde(rename = "div")]
Div {
style: Option<String>,
children: Vec<MessageElement>,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_complex_message() {
let msg = vec![
MessageElement::Author {
id: "user123".to_string(),
name: Some("Alice".to_string()),
avatar: Some("http://example.com/alice.png".to_string()),
},
MessageElement::Text {
text: "Hello, ".to_string(),
},
MessageElement::Bold {
children: vec![MessageElement::Text {
text: "world".to_string(),
}],
},
MessageElement::Image {
src: "http://example.com/image.png".to_string(),
title: None,
width: Some(100),
height: Some(100),
cache: None,
timeout: None,
},
];
let serialized = serde_json::to_string_pretty(&msg).unwrap();
println!("{}", serialized);
}
#[test]
fn test_serialize_quote_message() {
let quote_content = MessageElement::Quote {
id: "prev_msg_id_123".to_string(),
forward: None,
children: vec![
MessageElement::Author {
id: "user456".to_string(),
name: Some("Bob".to_string()),
avatar: None,
},
MessageElement::Text {
text: "This was the original message.".to_string(),
},
],
};
let main_message = vec![
MessageElement::Text {
text: "Replying to Bob: ".to_string(),
},
quote_content,
MessageElement::Text {
text: "What do you think?".to_string(),
},
];
let serialized = serde_json::to_string_pretty(&main_message).unwrap();
println!("{}", serialized);
}
}