slack_blocks/elems/select/
mod.rs

1//! # Select Menu Element
2//!
3//! A select menu, just as with a standard HTML `<select>` tag,
4//! creates a drop down menu with a list of options for a user to choose.
5//!
6//! The select menu also includes type-ahead functionality, where a user can type
7//! a part or all of an option string to filter the list.
8//!
9//! To use interactive components, you will need to make some changes to prepare your app.
10//! Read our [guide to enabling interactivity 🔗].
11//!
12//! [Select Menu Element 🔗]: https://api.slack.com/reference/block-kit/block-elements#select
13//! [guide to enabling interactivity 🔗]: https://api.slack.com/interactivity/handling
14
15pub mod multi;
16
17pub mod conversation;
18pub mod external;
19pub mod public_channel;
20pub mod static_;
21pub mod user;
22
23#[doc(inline)]
24pub use conversation::Conversation;
25#[doc(inline)]
26pub use external::External;
27#[doc(inline)]
28pub use public_channel::PublicChannel;
29#[doc(inline)]
30pub use static_::Static;
31#[doc(inline)]
32pub use user::User;
33
34/// Select builder
35#[cfg(feature = "blox")]
36#[cfg_attr(docsrs, doc(cfg(feature = "blox")))]
37pub mod build {
38  use std::marker::PhantomData;
39
40  use super::*;
41  use crate::build::*;
42
43  /// Static marker structs for "multi" or "single"
44  #[allow(non_camel_case_types)]
45  pub mod choose {
46    /// Select one
47    #[derive(Debug, Clone, Copy)]
48    pub struct single;
49    /// Select many
50    #[derive(Debug, Clone, Copy)]
51    pub struct multi;
52  }
53
54  /// Static marker structs for the data source of the select
55  #[allow(non_camel_case_types)]
56  pub mod data_source {
57    use super::*;
58    /// User select
59    #[derive(Debug, Clone, Copy)]
60    pub struct users;
61
62    /// Static select
63    #[derive(Debug, Clone, Copy)]
64    pub struct static_;
65
66    /// External select
67    #[derive(Debug, Clone, Copy)]
68    pub struct external;
69
70    /// Conversations select
71    #[derive(Debug, Clone, Copy)]
72    pub struct conversations;
73
74    /// Public channel select
75    #[derive(Debug, Clone, Copy)]
76    pub struct public_channels;
77
78    /// Associate a builder with a marker struct
79    pub trait SelectSubBuilder<M> {
80      /// Builder associated with marker struct
81      type SubBuilder;
82
83      /// Create the builder
84      fn builder() -> Self::SubBuilder;
85    }
86
87    impl SelectSubBuilder<choose::multi> for users {
88      type SubBuilder = user::build::MultiUserBuilderInit<'static>;
89      fn builder() -> Self::SubBuilder {
90        multi::User::builder()
91      }
92    }
93    impl SelectSubBuilder<choose::single> for users {
94      type SubBuilder = user::build::UserBuilderInit<'static>;
95      fn builder() -> Self::SubBuilder {
96        User::builder()
97      }
98    }
99    impl SelectSubBuilder<choose::multi> for static_ {
100      type SubBuilder = super::static_::build::MultiStaticBuilderInit<'static>;
101      fn builder() -> Self::SubBuilder {
102        multi::Static::builder()
103      }
104    }
105    impl SelectSubBuilder<choose::single> for static_ {
106      type SubBuilder = super::static_::build::StaticBuilderInit<'static>;
107      fn builder() -> Self::SubBuilder {
108        Static::builder()
109      }
110    }
111    impl SelectSubBuilder<choose::multi> for conversations {
112      type SubBuilder =
113        super::conversation::build::MultiConversationBuilderInit<'static>;
114      fn builder() -> Self::SubBuilder {
115        multi::Conversation::builder()
116      }
117    }
118    impl SelectSubBuilder<choose::single> for conversations {
119      type SubBuilder =
120        super::conversation::build::ConversationBuilderInit<'static>;
121      fn builder() -> Self::SubBuilder {
122        Conversation::builder()
123      }
124    }
125    impl SelectSubBuilder<choose::multi> for public_channels {
126      type SubBuilder =
127        super::public_channel::build::MultiPublicChannelBuilderInit<'static>;
128      fn builder() -> Self::SubBuilder {
129        multi::PublicChannel::builder()
130      }
131    }
132    impl SelectSubBuilder<choose::single> for public_channels {
133      type SubBuilder =
134        super::public_channel::build::PublicChannelBuilderInit<'static>;
135      fn builder() -> Self::SubBuilder {
136        PublicChannel::builder()
137      }
138    }
139    impl SelectSubBuilder<choose::multi> for external {
140      type SubBuilder =
141        super::external::build::MultiExternalBuilderInit<'static>;
142      fn builder() -> Self::SubBuilder {
143        multi::External::builder()
144      }
145    }
146    impl SelectSubBuilder<choose::single> for external {
147      type SubBuilder = super::external::build::ExternalBuilderInit<'static>;
148      fn builder() -> Self::SubBuilder {
149        External::builder()
150      }
151    }
152  }
153
154  /// Select builder methods
155  #[allow(non_camel_case_types)]
156  pub mod method {
157    /// SelectBuilder.choose_from
158    #[derive(Debug, Clone, Copy)]
159    pub struct choose_from;
160  }
161
162  /// Initial state for SelectBuilder
163  pub type SelectBuilderInit =
164    SelectBuilder<Set<choose::single>,
165                  RequiredMethodNotCalled<method::choose_from>>;
166
167  /// Build a select menu
168  #[derive(Debug, Clone)]
169  pub struct SelectBuilder<Count, DataSource>(PhantomData<(DataSource, Count)>);
170
171  impl<C, D> SelectBuilder<C, D> {
172    /// Construct a new select builder
173    pub fn new() -> Self {
174      Self(PhantomData::<_>)
175    }
176
177    /// Set the multiplicity of the Select (**Required**)
178    pub fn kind<C2>(self, _num: C2) -> SelectBuilder<Set<C2>, D> {
179      SelectBuilder(PhantomData::<_>)
180    }
181  }
182
183  impl<C, D> SelectBuilder<Set<C>, D> {
184    /// Set the data source of the Select (**Required**)
185    pub fn choose_from<D2: data_source::SelectSubBuilder<C>>(
186      self,
187      _choose: D2)
188      -> D2::SubBuilder {
189      D2::builder()
190    }
191  }
192}
193
194/// Marker structs for whether users can select one or many list items.
195///
196/// Used to inform builder structs what kind of select element to build.
197pub mod select_kind {
198  /// Users can select many items from the list.
199  #[derive(Copy, Clone, Debug)]
200  pub struct Multi;
201
202  /// Users can select one item from the list.
203  #[derive(Copy, Clone, Debug)]
204  pub struct Single;
205}
206
207#[cfg(feature = "validation")]
208mod validate {
209  use crate::{text, val_helpr::*};
210
211  pub(super) fn placeholder(text: &text::Text) -> ValidatorResult {
212    below_len("Select Placeholder text", 150, text.as_ref())
213  }
214}