block_kit/composition/
text.rs1use crate::composition::text::Text::Plain;
2use serde::Serialize;
3
4const PLAIN_TEXT: &str = "plain_text";
8const MARKDOWN: &str = "mrkdwn";
9
10#[derive(Debug, Serialize, Clone)]
11#[serde(untagged)]
12pub enum Text {
13 Plain(PlainText),
14 Markdown(MarkdownText),
15}
16
17#[derive(Debug, Serialize, Clone)]
18pub struct PlainText {
19 #[serde(rename = "type")]
20 type_name: &'static str,
21 text: String,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 emoji: Option<bool>,
24}
25
26#[derive(Debug, Serialize, Clone)]
27pub struct MarkdownText {
28 #[serde(rename = "type")]
29 type_name: &'static str,
30 text: String,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 verbatim: Option<bool>,
33}
34
35impl From<&str> for PlainText {
36 fn from(s: &str) -> Self {
37 PlainText::new(s)
38 }
39}
40
41impl From<String> for PlainText {
42 fn from(s: String) -> Self {
43 PlainText::new(s)
44 }
45}
46
47impl From<&str> for MarkdownText {
48 fn from(s: &str) -> Self {
49 MarkdownText::new(s)
50 }
51}
52
53impl From<String> for MarkdownText {
54 fn from(s: String) -> Self {
55 MarkdownText::new(s)
56 }
57}
58
59impl Default for Text {
60 fn default() -> Self {
61 Plain(PlainText::default())
62 }
63}
64
65impl Default for PlainText {
66 fn default() -> Self {
67 PlainText {
68 type_name: PLAIN_TEXT,
69 text: String::default(),
70 emoji: Option::default(),
71 }
72 }
73}
74
75impl Default for MarkdownText {
76 fn default() -> Self {
77 MarkdownText {
78 type_name: MARKDOWN,
79 text: String::default(),
80 verbatim: Option::default(),
81 }
82 }
83}
84
85impl PlainText {
86 pub fn new(text: impl Into<String>) -> Self {
87 PlainText {
88 text: text.into(),
89 ..PlainText::default()
90 }
91 }
92
93 pub fn emoji(mut self, emoji: bool) -> Self {
94 self.emoji = Some(emoji);
95 self
96 }
97}
98
99impl MarkdownText {
100 pub fn new(text: impl Into<String>) -> Self {
101 MarkdownText {
102 text: text.into(),
103 ..MarkdownText::default()
104 }
105 }
106
107 pub fn verbatim(mut self, verbatim: bool) -> Self {
108 self.verbatim = Some(verbatim);
109 self
110 }
111}
112
113#[cfg(test)]
114mod test {
115 use crate::composition::text::{MarkdownText, PlainText, Text};
116
117 #[test]
118 fn test_ser_new() {
119 let text = Text::Plain(PlainText::new("plain"));
120 let json = serde_json::to_string_pretty(&text).unwrap();
121 let expected = r#"{
122 "type": "plain_text",
123 "text": "plain"
124}"#;
125 assert_eq!(json, expected);
126
127 let text = Text::Markdown(MarkdownText::new("*markdown*"));
128 let json = serde_json::to_string_pretty(&text).unwrap();
129 let expected = r#"{
130 "type": "mrkdwn",
131 "text": "*markdown*"
132}"#;
133 assert_eq!(json, expected);
134 }
135
136 #[test]
137 fn test_ser_plain() {
138 let plain: PlainText = "plain".into();
139 let json = serde_json::to_string_pretty(&plain).unwrap();
140 let expected = r#"{
141 "type": "plain_text",
142 "text": "plain"
143}"#;
144 assert_eq!(json, expected);
145 }
146
147 #[test]
148 fn test_ser_plain_emoji() {
149 let plain: PlainText = "plain".into();
150 let plain = plain.emoji(false);
151 let json = serde_json::to_string_pretty(&plain).unwrap();
152 let expected = r#"{
153 "type": "plain_text",
154 "text": "plain",
155 "emoji": false
156}"#;
157 assert_eq!(json, expected);
158 }
159
160 #[test]
161 fn test_ser_markdown() {
162 let markdown: MarkdownText = "*markdown*".into();
163 let json = serde_json::to_string_pretty(&markdown).unwrap();
164 let expected = r#"{
165 "type": "mrkdwn",
166 "text": "*markdown*"
167}"#;
168 assert_eq!(json, expected);
169 }
170
171 #[test]
172 fn test_ser_markdown_verbatim() {
173 let markdown: MarkdownText = "*markdown*".into();
174 let markdown = markdown.verbatim(false);
175 let json = serde_json::to_string_pretty(&markdown).unwrap();
176 let expected = r#"{
177 "type": "mrkdwn",
178 "text": "*markdown*",
179 "verbatim": false
180}"#;
181 assert_eq!(json, expected);
182 }
183}