slack_web_api/entity/block_kit/
block.rs

1use crate::{BlockElementImage, BlockElementPlaneTextInput, CompositionObjectText, SlackBlockElement, SlackBlockKitCompositionObject};
2use serde_derive::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[serde(untagged)]
6pub enum SlackBlock {
7    Action(SlackBlockAction),
8    Context(SlackBlockContext),
9    Divider(SlackBlockDivider),
10    File(SlackBlockFile),
11    Header(SlackBlockHeader),
12    Image(SlackBlockImage),
13    Input(SlackBlockInput),
14    Section(SlackBlockSection),
15    Video(SlackBlockVideo),
16}
17
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct SlackBlockAction {
21    #[serde(rename = "type")]
22    pub block_type: String,
23    pub elements: Vec<SlackBlockElement>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub block_id: Option<String>,
26}
27
28impl Default for SlackBlockAction {
29    fn default() -> Self {
30        SlackBlockAction {
31            block_type: "actions".to_string(),
32            elements: vec![],
33            block_id: None,
34        }
35    }
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct SlackBlockContext {
40    #[serde(rename = "type")]
41    block_type: String,
42    elements: Vec<SlackBlockContentFieldElement>,
43    #[serde(skip_serializing_if = "Option::is_none")]
44    block_id: Option<String>,
45}
46
47impl Default for SlackBlockContext {
48    fn default() -> Self {
49        SlackBlockContext {
50            block_type: "context".to_string(),
51            elements: vec![],
52            block_id: None,
53        }
54    }
55}
56
57impl SlackBlockContext {
58    pub fn new() -> SlackBlockContext {
59        SlackBlockContext::default()
60    }
61    pub fn element<E: Into<SlackBlockContentFieldElement>>(self, element: E) -> SlackBlockContext {
62        let mut block = self;
63        block.elements.push(element.into());
64        block
65    }
66}
67
68impl From<SlackBlockContext> for SlackBlock {
69    fn from(value: SlackBlockContext) -> Self {
70        SlackBlock::Context(value)
71    }
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75#[serde(untagged)]
76pub enum SlackBlockContentFieldElement {
77    Image(BlockElementImage),
78    Text(CompositionObjectText),
79}
80
81impl From<BlockElementImage> for SlackBlockContentFieldElement {
82    fn from(value: BlockElementImage) -> Self {
83        SlackBlockContentFieldElement::Image(value)
84    }
85}
86
87impl From<CompositionObjectText> for SlackBlockContentFieldElement {
88    fn from(value: CompositionObjectText) -> Self {
89        SlackBlockContentFieldElement::Text(value)
90    }
91}
92
93
94impl SlackBlockContext {
95    pub fn new_text<S: Into<String>>(text: S) -> SlackBlockContext {
96        SlackBlockContext {
97            elements: vec![
98                CompositionObjectText {
99                    text: text.into(),
100                    ..CompositionObjectText::default()
101                }.into()
102            ],
103            ..SlackBlockContext::default()
104        }
105    }
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct SlackBlockDivider {
110    #[serde(rename = "type")]
111    pub block_type: String,
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub block_id: Option<String>,
114}
115
116impl Default for SlackBlockDivider {
117    fn default() -> Self {
118        SlackBlockDivider {
119            block_type: "divider".to_string(),
120
121            block_id: None,
122        }
123    }
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct SlackBlockFile {
128    #[serde(rename = "type")]
129    pub block_type: String,
130    pub external_id: String,
131    pub source: String,
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub block_id: Option<String>,
134}
135
136impl SlackBlockFile {
137    pub fn new() -> SlackBlockFile {
138        SlackBlockFile::default()
139    }
140    pub fn external_id<S: Into<String>>(self, external_id: S) -> SlackBlockFile {
141        let mut block = self;
142        block.external_id = external_id.into();
143        block
144    }
145}
146
147impl Default for SlackBlockFile {
148    fn default() -> Self {
149        SlackBlockFile {
150            block_type: "file".to_string(),
151
152            external_id: "".to_string(),
153            source: "remote".to_string(),
154            block_id: None,
155        }
156    }
157}
158
159impl From<SlackBlockFile> for SlackBlock {
160    fn from(value: SlackBlockFile) -> Self {
161        SlackBlock::File(value)
162    }
163}
164#[derive(Debug, Clone, Serialize, Deserialize)]
165pub struct SlackBlockHeader {
166    #[serde(rename = "type")]
167    pub block_type: String,
168    pub text: CompositionObjectText,
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub block_id: Option<String>,
171}
172
173impl Default for SlackBlockHeader {
174    fn default() -> Self {
175        SlackBlockHeader {
176            block_type: "header".to_string(),
177            text: Default::default(),
178            block_id: None,
179        }
180    }
181}
182
183impl SlackBlockHeader {
184    pub fn new_text<S: Into<String>>(text: S) -> SlackBlockHeader {
185        SlackBlockHeader {
186            text: CompositionObjectText {
187                text: text.into(),
188                ..CompositionObjectText::default()
189            },
190            ..SlackBlockHeader::default()
191        }
192    }
193}
194
195impl From<SlackBlockHeader> for SlackBlock {
196    fn from(value: SlackBlockHeader) -> Self {
197        SlackBlock::Header(value)
198    }
199}
200
201#[derive(Debug, Clone, Serialize, Deserialize)]
202pub struct SlackBlockImage {
203    #[serde(rename = "type")]
204    pub block_type: String,
205    pub image_url: String,
206    pub alt_text: String,
207    pub title: BlockElementPlaneTextInput,
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub block_id: Option<String>,
210}
211
212impl Default for SlackBlockImage {
213    fn default() -> Self {
214        SlackBlockImage {
215            block_type: "image".to_string(),
216
217            image_url: "".to_string(),
218            alt_text: "".to_string(),
219            title: Default::default(),
220            block_id: None,
221        }
222    }
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
226pub struct SlackBlockInput {
227    #[serde(rename = "type")]
228    pub block_type: String,
229    pub label: BlockElementPlaneTextInput,
230    #[serde(skip_serializing_if = "Option::is_none")]
231    pub element: Option<SlackBlockElement>,
232    #[serde(skip_serializing_if = "Option::is_none")]
233    pub dispatch_action: Option<bool>,
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub block_id: Option<String>,
236    #[serde(skip_serializing_if = "Option::is_none")]
237    pub hint: Option<BlockElementPlaneTextInput>,
238    #[serde(skip_serializing_if = "Option::is_none")]
239    pub optional: Option<bool>,
240}
241
242impl Default for SlackBlockInput {
243    fn default() -> Self {
244        SlackBlockInput {
245            block_type: "input".to_string(),
246            label: Default::default(),
247            element: None,
248            dispatch_action: None,
249            block_id: None,
250            hint: None,
251            optional: None,
252        }
253    }
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct SlackBlockSection {
258    #[serde(rename = "type")]
259    pub block_type: String,
260    pub text: BlockElementPlaneTextInput,
261    #[serde(skip_serializing_if = "Option::is_none")]
262    pub block_id: Option<String>,
263    #[serde(skip_serializing_if = "Option::is_none")]
264    pub fields: Option<Vec<BlockElementPlaneTextInput>>,
265    #[serde(skip_serializing_if = "Option::is_none")]
266    pub accessory: Option<SlackBlockElement>,
267}
268
269impl Default for SlackBlockSection {
270    fn default() -> Self {
271        SlackBlockSection {
272            block_type: "section".to_string(),
273
274            text: Default::default(),
275            block_id: None,
276            fields: None,
277            accessory: None,
278        }
279    }
280}
281
282#[derive(Debug, Default, Clone, Serialize, Deserialize)]
283pub struct SlackBlockVideo {
284    pub alt_text: String,
285    #[serde(skip_serializing_if = "Option::is_none")]
286    pub author_name: Option<String>,
287    #[serde(skip_serializing_if = "Option::is_none")]
288    pub block_id: Option<String>,
289    #[serde(skip_serializing_if = "Option::is_none")]
290    pub description: Option<BlockElementPlaneTextInput>,
291    #[serde(skip_serializing_if = "Option::is_none")]
292    pub provider_icon_url: Option<String>,
293    #[serde(skip_serializing_if = "Option::is_none")]
294    pub provider_name: Option<String>,
295    #[serde(skip_serializing_if = "Option::is_none")]
296    pub title: Option<BlockElementPlaneTextInput>,
297    #[serde(skip_serializing_if = "Option::is_none")]
298    pub title_url: Option<String>,
299    pub thumbnail_url: String,
300    pub video_url: String,
301}