Skip to main content

block_kit/composition/
text.rs

1use crate::composition::text::Text::Plain;
2use serde::Serialize;
3
4/// An object containing some text, formatted either as `plain_text` or using `mrkdwn`,
5/// our proprietary textual markup that's just different enough from Markdown to frustrate you.
6
7const 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}