slack_messaging/blocks/elements/select_menus/
public_channels.rs

1use crate::composition_objects::{ConfirmationDialog, Plain, Text};
2use crate::validators::*;
3
4use serde::Serialize;
5use slack_messaging_derive::Builder;
6
7/// [Select menu of public channels](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element#channels_select)
8/// representation
9///
10/// # Fields and Validations
11///
12/// For more details, see the [official
13/// documentation](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element#channels_select).
14///
15/// | Field | Type | Required | Validation |
16/// |-------|------|----------|------------|
17/// | action_id | String | No | Max length 255 characters |
18/// | initial_channel | String | No | N/A |
19/// | confirm | [ConfirmationDialog] | No | N/A |
20/// | response_url_enabled | bool | No | N/A |
21/// | focus_on_load | bool | No | N/A |
22/// | placeholder | [Text]<[Plain]> | No | Max length 150 characters |
23///
24/// # Example
25///
26/// ```
27/// use slack_messaging::plain_text;
28/// use slack_messaging::blocks::elements::SelectMenuPublicChannels;
29/// # use std::error::Error;
30///
31/// # fn try_main() -> Result<(), Box<dyn Error>> {
32/// let menu = SelectMenuPublicChannels::builder()
33///     .action_id("text1234")
34///     .placeholder(plain_text!("Select an item")?)
35///     .build()?;
36///
37/// let expected = serde_json::json!({
38///     "type": "channels_select",
39///     "action_id": "text1234",
40///     "placeholder": {
41///         "type": "plain_text",
42///         "text": "Select an item"
43///     }
44/// });
45///
46/// let json = serde_json::to_value(menu).unwrap();
47///
48/// assert_eq!(json, expected);
49///
50/// // If your object has any validation errors, the build method returns Result::Err
51/// let menu = SelectMenuPublicChannels::builder()
52///     .action_id("text1234")
53///     .placeholder(plain_text!("{}", "verrrrry long text".repeat(100))?)
54///     .build();
55///
56/// assert!(menu.is_err());
57/// #     Ok(())
58/// # }
59/// # fn main() {
60/// #     try_main().unwrap()
61/// # }
62/// ```
63#[derive(Debug, Default, Clone, Serialize, PartialEq, Builder)]
64#[serde(tag = "type", rename = "channels_select")]
65pub struct SelectMenuPublicChannels {
66    #[serde(skip_serializing_if = "Option::is_none")]
67    #[builder(validate("text::max_255"))]
68    pub(crate) action_id: Option<String>,
69
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub(crate) initial_channel: Option<String>,
72
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub(crate) confirm: Option<ConfirmationDialog>,
75
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub(crate) response_url_enabled: Option<bool>,
78
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub(crate) focus_on_load: Option<bool>,
81
82    #[serde(skip_serializing_if = "Option::is_none")]
83    #[builder(validate("text_object::max_150"))]
84    pub(crate) placeholder: Option<Text<Plain>>,
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90    use crate::composition_objects::test_helpers::*;
91    use crate::errors::*;
92
93    #[test]
94    fn it_implements_builder() {
95        let expected = SelectMenuPublicChannels {
96            action_id: Some("select_0".into()),
97            initial_channel: Some("User0".into()),
98            confirm: Some(confirm()),
99            response_url_enabled: Some(true),
100            focus_on_load: Some(true),
101            placeholder: Some(plain_text("Select item")),
102        };
103
104        let val = SelectMenuPublicChannels::builder()
105            .set_action_id(Some("select_0"))
106            .set_initial_channel(Some("User0"))
107            .set_confirm(Some(confirm()))
108            .set_response_url_enabled(Some(true))
109            .set_focus_on_load(Some(true))
110            .set_placeholder(Some(plain_text("Select item")))
111            .build()
112            .unwrap();
113
114        assert_eq!(val, expected);
115
116        let val = SelectMenuPublicChannels::builder()
117            .action_id("select_0")
118            .initial_channel("User0")
119            .confirm(confirm())
120            .response_url_enabled(true)
121            .focus_on_load(true)
122            .placeholder(plain_text("Select item"))
123            .build()
124            .unwrap();
125
126        assert_eq!(val, expected);
127    }
128
129    #[test]
130    fn it_requires_action_id_less_than_255_characters_long() {
131        let err = SelectMenuPublicChannels::builder()
132            .action_id("a".repeat(256))
133            .build()
134            .unwrap_err();
135        assert_eq!(err.object(), "SelectMenuPublicChannels");
136
137        let errors = err.field("action_id");
138        assert!(errors.includes(ValidationErrorKind::MaxTextLength(255)));
139    }
140
141    #[test]
142    fn it_requires_placeholder_text_less_than_150_characters_long() {
143        let err = SelectMenuPublicChannels::builder()
144            .placeholder(plain_text("a".repeat(151)))
145            .build()
146            .unwrap_err();
147        assert_eq!(err.object(), "SelectMenuPublicChannels");
148
149        let errors = err.field("placeholder");
150        assert!(errors.includes(ValidationErrorKind::MaxTextLength(150)));
151    }
152}