slack_messaging/blocks/actions.rs
1use super::elements::{
2 Button, Checkboxes, DatePicker, DatetimePicker, MultiSelectMenu, OverflowMenu,
3 RadioButtonGroup, SelectMenu, TimePicker, WorkflowButton,
4};
5use serde::Serialize;
6
7/// [Actions block](https://docs.slack.dev/reference/block-kit/blocks/actions-block)
8/// representation.
9///
10/// # Example
11///
12/// The following is reproduction of [the 1st sample actions](https://docs.slack.dev/reference/block-kit/blocks/actions-block#examples).
13///
14/// ```
15/// # use slack_messaging::blocks::Actions;
16/// # use slack_messaging::blocks::elements::{Button, Select};
17/// # use slack_messaging::blocks::elements::select_menu_types::StaticOptions;
18/// # use slack_messaging::composition_objects::Opt;
19/// # use slack_messaging::plain_text;
20/// let actions = Actions::builder()
21/// .block_id("actions1")
22/// .element(
23/// Select::<StaticOptions>::builder()
24/// .action_id("select_2")
25/// .placeholder("Which witch is the witchiest witch?")
26/// .set_options(
27/// vec![
28/// Opt::builder().text(plain_text!("Matilda")).value("matilda").build(),
29/// Opt::builder().text(plain_text!("Glinda")).value("glinda").build(),
30/// Opt::builder().text(plain_text!("Granny Weatherwax")).value("grannyWeatherwax").build(),
31/// Opt::builder().text(plain_text!("Hermione")).value("hermione").build(),
32/// ]
33/// )
34/// .build()
35/// )
36/// .element(
37/// Button::builder()
38/// .action_id("button_1")
39/// .value("cancel")
40/// .text("Cancel")
41/// .build()
42/// )
43/// .build();
44///
45/// let expected = serde_json::json!({
46/// "type": "actions",
47/// "block_id": "actions1",
48/// "elements": [
49/// {
50/// "type": "static_select",
51/// "action_id": "select_2",
52/// "placeholder": {
53/// "type": "plain_text",
54/// "text": "Which witch is the witchiest witch?"
55/// },
56/// "options": [
57/// {
58/// "text": {
59/// "type": "plain_text",
60/// "text": "Matilda"
61/// },
62/// "value": "matilda"
63/// },
64/// {
65/// "text": {
66/// "type": "plain_text",
67/// "text": "Glinda"
68/// },
69/// "value": "glinda"
70/// },
71/// {
72/// "text": {
73/// "type": "plain_text",
74/// "text": "Granny Weatherwax"
75/// },
76/// "value": "grannyWeatherwax"
77/// },
78/// {
79/// "text": {
80/// "type": "plain_text",
81/// "text": "Hermione"
82/// },
83/// "value": "hermione"
84/// }
85/// ]
86/// },
87/// {
88/// "type": "button",
89/// "text": {
90/// "type": "plain_text",
91/// "text": "Cancel"
92/// },
93/// "value": "cancel",
94/// "action_id": "button_1"
95/// }
96/// ]
97/// });
98///
99/// let json = serde_json::to_value(actions).unwrap();
100///
101/// assert_eq!(json, expected);
102/// ```
103///
104/// And the following is the [2nd sample actions](https://docs.slack.dev/reference/block-kit/blocks/actions-block#examples).
105///
106/// ```
107/// # use slack_messaging::blocks::Actions;
108/// # use slack_messaging::blocks::elements::{Button, DatePicker, OverflowMenu};
109/// # use slack_messaging::composition_objects::Opt;
110/// # use slack_messaging::plain_text;
111/// let actions = Actions::builder()
112/// .block_id("actionblock789")
113/// .element(
114/// DatePicker::builder()
115/// .action_id("datepicker123")
116/// .initial_date("1990-04-28")
117/// .placeholder("Select a date")
118/// .build()
119/// )
120/// .element(
121/// OverflowMenu::builder()
122/// .action_id("overflow")
123/// .option(
124/// Opt::builder()
125/// .text(plain_text!("*this is plain_text text*"))
126/// .value("value-0")
127/// .build()
128/// )
129/// .option(
130/// Opt::builder()
131/// .text(plain_text!("*this is plain_text text*"))
132/// .value("value-1")
133/// .build()
134/// )
135/// .option(
136/// Opt::builder()
137/// .text(plain_text!("*this is plain_text text*"))
138/// .value("value-2")
139/// .build()
140/// )
141/// .option(
142/// Opt::builder()
143/// .text(plain_text!("*this is plain_text text*"))
144/// .value("value-3")
145/// .build()
146/// )
147/// .option(
148/// Opt::builder()
149/// .text(plain_text!("*this is plain_text text*"))
150/// .value("value-4")
151/// .build()
152/// )
153/// .build()
154/// )
155/// .element(
156/// Button::builder()
157/// .action_id("button")
158/// .value("click_me_123")
159/// .text("Click Me")
160/// .build()
161/// )
162/// .build();
163///
164/// let expected = serde_json::json!({
165/// "type": "actions",
166/// "block_id": "actionblock789",
167/// "elements": [
168/// {
169/// "type": "datepicker",
170/// "action_id": "datepicker123",
171/// "initial_date": "1990-04-28",
172/// "placeholder": {
173/// "type": "plain_text",
174/// "text": "Select a date"
175/// }
176/// },
177/// {
178/// "type": "overflow",
179/// "action_id": "overflow",
180/// "options": [
181/// {
182/// "text": {
183/// "type": "plain_text",
184/// "text": "*this is plain_text text*"
185/// },
186/// "value": "value-0"
187/// },
188/// {
189/// "text": {
190/// "type": "plain_text",
191/// "text": "*this is plain_text text*"
192/// },
193/// "value": "value-1"
194/// },
195/// {
196/// "text": {
197/// "type": "plain_text",
198/// "text": "*this is plain_text text*"
199/// },
200/// "value": "value-2"
201/// },
202/// {
203/// "text": {
204/// "type": "plain_text",
205/// "text": "*this is plain_text text*"
206/// },
207/// "value": "value-3"
208/// },
209/// {
210/// "text": {
211/// "type": "plain_text",
212/// "text": "*this is plain_text text*"
213/// },
214/// "value": "value-4"
215/// }
216/// ]
217/// },
218/// {
219/// "type": "button",
220/// "text": {
221/// "type": "plain_text",
222/// "text": "Click Me"
223/// },
224/// "value": "click_me_123",
225/// "action_id": "button"
226/// }
227/// ]
228/// });
229///
230/// let json = serde_json::to_value(actions).unwrap();
231///
232/// assert_eq!(json, expected);
233/// ```
234///
235#[derive(Debug, Clone, Serialize)]
236pub struct Actions {
237 #[serde(rename = "type")]
238 pub(super) kind: &'static str,
239
240 pub(super) elements: Vec<ActionsElement>,
241
242 #[serde(skip_serializing_if = "Option::is_none")]
243 pub(super) block_id: Option<String>,
244}
245
246/// Objects that can be an element of the [Actions]'s elements field.
247#[derive(Debug, Clone, Serialize)]
248#[serde(untagged)]
249pub enum ActionsElement {
250 /// [Button element](https://docs.slack.dev/reference/block-kit/block-elements/button-element)
251 /// representation
252 Button(Box<Button>),
253
254 /// [Checkbox group](https://docs.slack.dev/reference/block-kit/block-elements/checkboxes-element)
255 /// representation
256 Checkboxes(Box<Checkboxes>),
257
258 /// [Date picker element](https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element)
259 /// representation
260 DatePicker(Box<DatePicker>),
261
262 /// [Datetime picker element](https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element)
263 /// representation
264 DatetimePicker(Box<DatetimePicker>),
265
266 /// [Multi-select menu element](https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element)
267 /// representation
268 MultiSelectMenu(Box<MultiSelectMenu>),
269
270 /// [Overflow menu element](https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element)
271 /// representation
272 OverflowMenu(Box<OverflowMenu>),
273
274 /// [Radio buton group element](https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element)
275 /// representation
276 RadioButtonGroup(Box<RadioButtonGroup>),
277
278 /// [Select menu element](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element)
279 /// representation
280 SelectMenu(Box<SelectMenu>),
281
282 /// [Time picker element](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)
283 /// representation
284 TimePicker(Box<TimePicker>),
285
286 /// [Workflow button element](https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element)
287 /// representation
288 WorkflowButton(Box<WorkflowButton>),
289}
290
291macro_rules! actions_from {
292 ($($ty:ident),*) => {
293 $(
294 impl From<$ty> for ActionsElement {
295 fn from(value: $ty) -> Self {
296 Self::$ty(Box::new(value))
297 }
298 }
299 )*
300 }
301}
302
303actions_from! {
304 Button,
305 Checkboxes,
306 DatePicker,
307 DatetimePicker,
308 MultiSelectMenu,
309 OverflowMenu,
310 RadioButtonGroup,
311 SelectMenu,
312 TimePicker,
313 WorkflowButton
314}