open_lark/card/components/content_components/
plain_text.rs

1use serde::{Deserialize, Serialize};
2
3use crate::card::icon::FeishuCardTextIcon;
4
5/// 文本组件
6#[derive(Debug, Serialize, Deserialize)]
7pub struct FeishuCardText {
8    /// 组件的标签。普通文本组件的标签为 div。
9    tag: String,
10    /// 配置卡片的普通文本信息。
11    #[serde(skip_serializing_if = "Option::is_none")]
12    text: Option<PlainText>,
13    /// 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。
14    #[serde(skip_serializing_if = "Option::is_none")]
15    icon: Option<FeishuCardTextIcon>,
16}
17
18impl Default for FeishuCardText {
19    fn default() -> Self {
20        FeishuCardText {
21            tag: "div".to_string(),
22            text: None,
23            icon: None,
24        }
25    }
26}
27
28impl FeishuCardText {
29    pub fn new() -> Self {
30        FeishuCardText::default()
31    }
32
33    pub fn text(mut self, text: PlainText) -> Self {
34        self.text = Some(text);
35        self
36    }
37
38    pub fn icon(mut self, icon: FeishuCardTextIcon) -> Self {
39        self.icon = Some(icon);
40        self
41    }
42}
43
44/// text 结构体
45#[derive(Debug, Serialize, Deserialize)]
46pub struct PlainText {
47    /// 文本类型的标签。可取值:
48    ///
49    /// plain_text:普通文本内容
50    /// lark_md:支持部分 Markdown 语法的文本内容。详情参考下文 lark_md 支持的 Markdown 语法
51    tag: String,
52    /// 文本内容。当 tag 为 lark_md 时,支持部分 Markdown 语法的文本内容。
53    content: String,
54    /// 文本大小。可取值如下所示。如果你填写了其它值,卡片将展示为 normal
55    /// 字段对应的字号。你也可分别为移动端和桌面端定义不同的字号
56    #[serde(skip_serializing_if = "Option::is_none")]
57    text_size: Option<String>,
58    /// 文本的颜色。仅在 tag 为 plain_text 时生效。可取值:
59    ///
60    /// default:客户端浅色主题模式下为黑色;客户端深色主题模式下为白色
61    /// 颜色的枚举值。详情参考颜色枚举值
62    #[serde(skip_serializing_if = "Option::is_none")]
63    text_color: Option<String>,
64    /// 文本对齐方式。可取值:
65    ///
66    /// - left:左对齐
67    /// - center:居中对齐
68    /// - right:右对齐
69    #[serde(skip_serializing_if = "Option::is_none")]
70    text_align: Option<String>,
71    /// 内容最大显示行数,超出设置行的内容用 ... 省略。
72    #[serde(skip_serializing_if = "Option::is_none")]
73    lines: Option<i32>,
74}
75
76impl Default for PlainText {
77    fn default() -> Self {
78        PlainText {
79            tag: "plain_text".to_string(),
80            content: "".to_string(),
81            text_size: None,
82            text_color: None,
83            text_align: None,
84            lines: None,
85        }
86    }
87}
88
89impl PlainText {
90    pub fn text(content: &str) -> Self {
91        Self {
92            tag: "plain_text".to_string(),
93            content: content.to_string(),
94            text_size: None,
95            text_color: None,
96            text_align: None,
97            lines: None,
98        }
99    }
100
101    pub fn markdown(content: &str) -> Self {
102        Self {
103            tag: "lark_md".to_string(),
104            content: content.to_string(),
105            text_size: None,
106            text_color: None,
107            text_align: None,
108            lines: None,
109        }
110    }
111
112    /// 文本类型的标签。可取值:
113    ///
114    /// plain_text:普通文本内容
115    /// lark_md:支持部分 Markdown 语法的文本内容
116    pub fn tag(mut self, tag: &str) -> Self {
117        self.tag = tag.to_string();
118        self
119    }
120
121    /// 文本内容
122    pub fn content(mut self, content: &str) -> Self {
123        self.content = content.to_string();
124        self
125    }
126
127    pub fn text_size(mut self, text_size: &str) -> Self {
128        self.text_size = Some(text_size.to_string());
129        self
130    }
131
132    pub fn text_color(mut self, text_color: &str) -> Self {
133        self.text_color = Some(text_color.to_string());
134        self
135    }
136
137    pub fn text_align(mut self, text_align: &str) -> Self {
138        self.text_align = Some(text_align.to_string());
139        self
140    }
141
142    pub fn lines(mut self, lines: i32) -> Self {
143        self.lines = Some(lines);
144        self
145    }
146}
147
148#[cfg(test)]
149mod test {
150    use serde_json::json;
151
152    #[test]
153    fn test_message_card_text() {
154        use super::*;
155        let text = FeishuCardText::new()
156            .text(
157                PlainText::text("这是一段普通文本示例。")
158                    .text_size("cus-0")
159                    .text_align("center")
160                    .text_color("default"),
161            )
162            .icon(
163                FeishuCardTextIcon::new()
164                    .token("app-default_filled")
165                    .color("blue"),
166            );
167        let json = json!({
168                "tag": "div",
169                "text": {
170                  "tag": "plain_text",
171                  "content": "这是一段普通文本示例。",
172                  "text_size": "cus-0",
173                  "text_align": "center",
174                  "text_color": "default"
175                },
176                "icon": {
177                  "tag": "standard_icon",
178                  "token": "app-default_filled",
179                  "color": "blue"
180                }
181              }
182        );
183        assert_eq!(json, serde_json::to_value(&text).unwrap());
184    }
185}