slack_blocks/elems/select/multi/
static_.rs

1//! # Multi-select menu with static options
2//!
3//! [slack api docs 🔗](https://api.slack.com/reference/block-kit/block-elements#static_multi_select)
4//!
5//! This is the simplest form of select menu,
6//! with a static list of options passed in when defining the element.
7//!
8//! Works in [blocks 🔗]: Section, Input
9//!
10//! [slack api docs 🔗]: https://api.slack.com/reference/block-kit/block-elements#radio
11//! [blocks 🔗]: https://api.slack.com/reference/block-kit/blocks
12
13use std::borrow::Cow;
14
15use compose::{opt::NoUrl, Confirm};
16use serde::{Deserialize, Serialize};
17#[cfg(feature = "validation")]
18use validator::Validate;
19
20#[cfg(feature = "validation")]
21use crate::val_helpr::ValidationResult;
22use crate::{compose, elems::select::static_::build, text};
23
24type OptGroup<'a> = compose::OptGroup<'a, text::Plain, NoUrl>;
25type Opt<'a> = compose::Opt<'a, text::Plain, NoUrl>;
26type OptOrOptGroup<'a> = compose::OptOrOptGroup<'a, text::Plain, NoUrl>;
27
28/// # Multi-select menu with static options
29///
30/// [slack api docs 🔗](https://api.slack.com/reference/block-kit/block-elements#static_multi_select)
31///
32/// This is the simplest form of select menu,
33/// with a static list of options passed in when defining the element.
34///
35/// Works in [blocks 🔗]: Section, Input
36///
37/// [slack api docs 🔗]: https://api.slack.com/reference/block-kit/block-elements#radio
38/// [blocks 🔗]: https://api.slack.com/reference/block-kit/blocks
39#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)]
40#[cfg_attr(feature = "validation", derive(Validate))]
41pub struct Static<'a> {
42  #[cfg_attr(feature = "validation",
43             validate(custom = "crate::elems::select::validate::placeholder"))]
44  pub(in crate::elems::select) placeholder: text::Text,
45
46  #[cfg_attr(feature = "validation", validate(length(max = 255)))]
47  pub(in crate::elems::select) action_id: Cow<'a, str>,
48
49  #[serde(skip_serializing_if = "Option::is_none")]
50  #[cfg_attr(feature = "validation", validate(length(max = 100)))]
51  pub(in crate::elems::select) options: Option<Vec<Opt<'a>>>,
52
53  #[serde(skip_serializing_if = "Option::is_none")]
54  #[cfg_attr(feature = "validation", validate(length(max = 100)))]
55  pub(in crate::elems::select) option_groups: Option<Vec<OptGroup<'a>>>,
56
57  #[serde(skip_serializing_if = "Option::is_none")]
58  #[cfg_attr(feature = "validation", validate)]
59  pub(in crate::elems::select) confirm: Option<Confirm>,
60
61  #[serde(skip_serializing_if = "Option::is_none")]
62  pub(in crate::elems::select) initial_options:
63    Option<Cow<'a, [OptOrOptGroup<'a>]>>,
64
65  #[cfg_attr(feature = "validation", validate(range(min = 1)))]
66  #[serde(skip_serializing_if = "Option::is_none")]
67  pub(in crate::elems::select) max_selected_items: Option<u32>,
68}
69
70impl<'a> Static<'a> {
71  /// Build a new static select element
72  ///
73  /// # Examples
74  /// ```
75  /// // TODO(#130): implement once input or section can accept this
76  /// ```
77  pub fn builder() -> build::MultiStaticBuilderInit<'a> {
78    build::MultiStaticBuilderInit::new()
79  }
80
81  /// Validate that this select element agrees with Slack's model requirements
82  ///
83  /// # Errors
84  /// - If `from_placeholder_and_action_id` was called with
85  ///     `placeholder` longer than 150 chars
86  /// - If `from_placeholder_and_action_id` was called with
87  ///     `action_id` longer than 255 chars
88  ///
89  /// # Example
90  /// ```
91  /// use slack_blocks::elems::select;
92  ///
93  /// let placeholder = r#"Hey I really would appreciate it if you chose
94  /// a channel relatively soon, so that we can figure out
95  /// where we need to send this poll, ok? it's kind of
96  /// important that you specify where this poll should be
97  /// sent, in case we haven't made that super clear.
98  /// If you understand, could you pick a channel, already??"#;
99  ///
100  /// let select = select::multi::Static::builder().placeholder(placeholder)
101  ///                                              .action_id("abc123")
102  ///                                              .options(std::iter::empty())
103  ///                                              .build();
104  ///
105  /// assert!(matches!(select.validate(), Err(_)))
106  /// ```
107  #[cfg(feature = "validation")]
108  #[cfg_attr(docsrs, doc(cfg(feature = "validation")))]
109  pub fn validate(&self) -> ValidationResult {
110    Validate::validate(self)
111  }
112}