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}