use std::{collections::HashMap, default::Default, str::FromStr};
use serde::{Deserialize, Serialize};
use crate::card::{FeishuCardHeaderTemplate, FeishuCardLanguage, FeishuCardStyle, TextTag};
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct FeishuCardTitle {
#[serde(skip_serializing_if = "Option::is_none")]
title: Option<Title>,
#[serde(skip_serializing_if = "Option::is_none")]
subtitle: Option<Title>,
#[serde(skip_serializing_if = "Option::is_none")]
text_tag_list: Option<Vec<TextTag>>,
#[serde(skip_serializing_if = "Option::is_none")]
i18n_text_tag_list: Option<HashMap<FeishuCardLanguage, Vec<TextTag>>>,
#[serde(skip_serializing_if = "Option::is_none")]
template: Option<FeishuCardHeaderTemplate>,
#[serde(skip_serializing_if = "Option::is_none")]
icon: Option<FeishuCardIcon>,
#[serde(skip_serializing_if = "Option::is_none")]
ud_icon: Option<FeishuCardUdIcon>,
}
impl FeishuCardTitle {
pub fn new() -> Self {
FeishuCardTitle::default()
}
pub fn title(mut self, title: Title) -> Self {
self.title = Some(title);
self
}
pub fn subtitle(mut self, subtitle: Title) -> Self {
self.subtitle = Some(subtitle);
self
}
pub fn icon(mut self, icon: FeishuCardIcon) -> Self {
self.icon = Some(icon);
self
}
pub fn ud_icon(mut self, ud_icon: FeishuCardUdIcon) -> Self {
self.ud_icon = Some(ud_icon);
self
}
pub fn template(mut self, template: &str) -> Self {
let template = FeishuCardHeaderTemplate::from_str(template).expect("invalid template");
self.template = Some(template);
self
}
pub fn text_tag_list(mut self, text_tag_list: Vec<TextTag>) -> Self {
self.text_tag_list = Some(text_tag_list);
self
}
pub fn i18n_text_tag_list(
mut self,
i18n_text_tag_list: HashMap<FeishuCardLanguage, Vec<TextTag>>,
) -> Self {
self.i18n_text_tag_list = Some(i18n_text_tag_list);
self
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Title {
tag: String,
#[serde(skip_serializing_if = "Option::is_none")]
content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
i18n: Option<HashMap<FeishuCardLanguage, String>>,
}
impl Default for Title {
fn default() -> Self {
Title {
tag: "plain_text".to_string(),
content: None,
i18n: None,
}
}
}
impl Title {
pub fn new(content: &str) -> Self {
Self::default().content(content)
}
pub fn content(mut self, content: &str) -> Self {
self.content = Some(content.to_string());
self
}
pub fn i18n(mut self, i18n: HashMap<FeishuCardLanguage, String>) -> Self {
self.i18n = Some(i18n);
self
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct FeishuCardIcon {
tag: String,
#[serde(skip_serializing_if = "Option::is_none")]
img_key: Option<String>,
}
impl Default for FeishuCardIcon {
fn default() -> Self {
FeishuCardIcon {
tag: "custom_icon".to_string(),
img_key: None,
}
}
}
impl FeishuCardIcon {
pub fn new() -> Self {
FeishuCardIcon::default()
}
pub fn img_key(mut self, img_key: &str) -> Self {
self.img_key = Some(img_key.to_string());
self
}
pub fn build(self) -> FeishuCardIcon {
self
}
}
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct FeishuCardUdIcon {
tag: String,
#[serde(skip_serializing_if = "Option::is_none")]
token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
style: Option<FeishuCardStyle>,
}
impl FeishuCardUdIcon {
pub fn new(token: &str) -> Self {
Self {
tag: "standard_icon".to_string(),
token: Some(token.to_string()),
..Default::default()
}
}
pub fn token(mut self, token: &str) -> Self {
self.token = Some(token.to_string());
self
}
pub fn style(mut self, style: FeishuCardStyle) -> Self {
self.style = Some(style);
self
}
}
#[cfg(test)]
mod test {
use serde_json::json;
use crate::card::{components::content_components::plain_text::PlainText, TextTag};
use super::*;
#[test]
fn test_title() {
let title = Title::new("content").i18n(
vec![
(FeishuCardLanguage::ZhCN, "中文".to_string()),
(FeishuCardLanguage::EnUS, "english".to_string()),
]
.into_iter()
.collect(),
);
let json = json!({"tag":"plain_text","content":"content","i18n":{"zh_cn":"中文","en_us":"english"}});
assert_eq!(serde_json::to_value(&title).unwrap(), json);
}
#[test]
fn test_feishu_card_title() {
let title = FeishuCardTitle::new()
.title(Title::new("示例标题"))
.subtitle(Title::new("示例文本"))
.template("blue")
.text_tag_list(vec![
TextTag::new()
.text(PlainText::text("标签 1"))
.color("neutral"),
TextTag::new()
.text(PlainText::text("标签 2"))
.color("neutral"),
])
.ud_icon(FeishuCardUdIcon::new("meego_colorful"));
let json = serde_json::to_value(&title).unwrap();
assert_eq!(
json,
json!({
"title": {
"tag": "plain_text",
"content": "示例标题"
},
"subtitle": {
"tag": "plain_text",
"content": "示例文本"
},
"text_tag_list": [
{
"tag": "text_tag",
"text": {
"tag": "plain_text",
"content": "标签 1"
},
"color": "neutral"
},
{
"tag": "text_tag",
"text": {
"tag": "plain_text",
"content": "标签 2"
},
"color": "neutral"
}
],
"template": "blue",
"ud_icon": {
"tag": "standard_icon",
"token": "meego_colorful"
}
})
);
}
}