slack_web_api/entity/block_kit/
block.rs1use 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}