slack_messaging/blocks/elements/select_menus/
conversations.rs

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