slack_messaging/composition_objects/
confirmation_dialog.rs

1use crate::composition_objects::{Plain, Text};
2use crate::validators::*;
3
4use serde::Serialize;
5use slack_messaging_derive::Builder;
6
7/// [Confirmation dialog object](https://docs.slack.dev/reference/block-kit/composition-objects/confirmation-dialog-object)
8/// representation.
9///
10/// # Fields and Validations
11///
12/// For more details, see the [official
13/// documentation](https://docs.slack.dev/reference/block-kit/composition-objects/confirmation-dialog-object).
14///
15/// | Field | Type | Required | Validation |
16/// |-------|------|----------|------------|
17/// | title | [Text]<[Plain]> | Yes | Max length 100 characters |
18/// | text | [Text]<[Plain]> | Yes | Max length 300 characters |
19/// | confirm | [Text]<[Plain]> | Yes | Max length 30 characters |
20/// | deny | [Text]<[Plain]> | Yes | Max length 30 characters |
21/// | style | &str | No | Must be either "primary" or "danger" |
22///
23/// # Example
24///
25/// ```
26/// use slack_messaging::plain_text;
27/// use slack_messaging::composition_objects::ConfirmationDialog;
28/// # use std::error::Error;
29///
30/// # fn try_main() -> Result<(), Box<dyn Error>> {
31/// let dialog = ConfirmationDialog::builder()
32///     .title(plain_text!("Are you sure?")?)
33///     .text(plain_text!("Wouldn't you prefer a good game of _chess_?")?)
34///     .confirm(plain_text!("Do it")?)
35///     .deny(plain_text!("Stop, I've changed my mind!")?)
36///     .primary()
37///     .build()?;
38///
39/// let expected = serde_json::json!({
40///     "title": {
41///         "type": "plain_text",
42///         "text": "Are you sure?"
43///     },
44///     "text": {
45///         "type": "plain_text",
46///         "text": "Wouldn't you prefer a good game of _chess_?"
47///     },
48///     "confirm": {
49///         "type": "plain_text",
50///         "text": "Do it"
51///     },
52///     "deny": {
53///         "type": "plain_text",
54///         "text": "Stop, I've changed my mind!"
55///     },
56///     "style": "primary"
57/// });
58///
59/// let json = serde_json::to_value(dialog).unwrap();
60///
61/// assert_eq!(json, expected);
62///
63/// // If your object has any validation errors, the build method returns Result::Err
64/// let dialog = ConfirmationDialog::builder()
65///     .text(plain_text!("Wouldn't you prefer a good game of _chess_?")?)
66///     .confirm(plain_text!("Do it")?)
67///     .deny(plain_text!("Stop, I've changed my mind!")?)
68///     .build();
69///
70/// assert!(dialog.is_err());
71/// #     Ok(())
72/// # }
73/// # fn main() {
74/// #     try_main().unwrap()
75/// # }
76/// ```
77#[derive(Debug, Clone, Serialize, PartialEq, Builder)]
78pub struct ConfirmationDialog {
79    #[builder(validate("required", "text_object::max_100"))]
80    pub(crate) title: Option<Text<Plain>>,
81
82    #[builder(validate("required", "text_object::max_300"))]
83    pub(crate) text: Option<Text<Plain>>,
84
85    #[builder(validate("required", "text_object::max_30"))]
86    pub(crate) confirm: Option<Text<Plain>>,
87
88    #[builder(validate("required", "text_object::max_30"))]
89    pub(crate) deny: Option<Text<Plain>>,
90
91    #[serde(skip_serializing_if = "Option::is_none")]
92    #[builder(private_setter)]
93    pub(crate) style: Option<&'static str>,
94}
95
96impl ConfirmationDialogBuilder {
97    /// set "primary" to style field
98    pub fn primary(self) -> Self {
99        self.style("primary")
100    }
101
102    /// set "danger" to style field
103    pub fn danger(self) -> Self {
104        self.style("danger")
105    }
106}
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111    use crate::composition_objects::test_helpers::*;
112    use crate::errors::*;
113
114    #[test]
115    fn it_implements_builder() {
116        let expected = ConfirmationDialog {
117            title: Some(plain_text("Are you sure?")),
118            text: Some(plain_text("Wouldn't you prefer a good game of _chess_?")),
119            confirm: Some(plain_text("Do it")),
120            deny: Some(plain_text("Stop, I've changed my mind!")),
121            style: Some("primary"),
122        };
123
124        let dialog = ConfirmationDialog::builder()
125            .set_title(Some(plain_text("Are you sure?")))
126            .set_text(Some(plain_text(
127                "Wouldn't you prefer a good game of _chess_?",
128            )))
129            .set_confirm(Some(plain_text("Do it")))
130            .set_deny(Some(plain_text("Stop, I've changed my mind!")))
131            .primary()
132            .build()
133            .unwrap();
134
135        assert_eq!(dialog, expected);
136
137        let dialog = ConfirmationDialog::builder()
138            .title(plain_text("Are you sure?"))
139            .text(plain_text("Wouldn't you prefer a good game of _chess_?"))
140            .confirm(plain_text("Do it"))
141            .deny(plain_text("Stop, I've changed my mind!"))
142            .primary()
143            .build()
144            .unwrap();
145
146        assert_eq!(dialog, expected);
147    }
148
149    #[test]
150    fn it_requires_title_field() {
151        let err = ConfirmationDialog::builder()
152            .text(plain_text("foo"))
153            .confirm(plain_text("bar"))
154            .deny(plain_text("baz"))
155            .build()
156            .unwrap_err();
157        assert_eq!(err.object(), "ConfirmationDialog");
158
159        let title_err = err.field("title");
160        assert!(title_err.includes(ValidationErrorKind::Required));
161    }
162
163    #[test]
164    fn it_requires_title_field_less_than_100_characters() {
165        let err = ConfirmationDialog::builder()
166            .title(plain_text("a".repeat(101)))
167            .text(plain_text("foo"))
168            .confirm(plain_text("bar"))
169            .deny(plain_text("baz"))
170            .build()
171            .unwrap_err();
172        assert_eq!(err.object(), "ConfirmationDialog");
173
174        let title_err = err.field("title");
175        assert!(title_err.includes(ValidationErrorKind::MaxTextLength(100)));
176    }
177
178    #[test]
179    fn it_requires_text_field() {
180        let err = ConfirmationDialog::builder()
181            .title(plain_text("foo"))
182            .confirm(plain_text("bar"))
183            .deny(plain_text("baz"))
184            .build()
185            .unwrap_err();
186        assert_eq!(err.object(), "ConfirmationDialog");
187
188        let text_err = err.field("text");
189        assert!(text_err.includes(ValidationErrorKind::Required));
190    }
191
192    #[test]
193    fn it_requires_text_field_less_than_300_characters() {
194        let err = ConfirmationDialog::builder()
195            .title(plain_text("foo"))
196            .text(plain_text("a".repeat(301)))
197            .confirm(plain_text("bar"))
198            .deny(plain_text("baz"))
199            .build()
200            .unwrap_err();
201        assert_eq!(err.object(), "ConfirmationDialog");
202
203        let text_err = err.field("text");
204        assert!(text_err.includes(ValidationErrorKind::MaxTextLength(300)));
205    }
206
207    #[test]
208    fn it_requires_confirm_field() {
209        let err = ConfirmationDialog::builder()
210            .title(plain_text("foo"))
211            .text(plain_text("bar"))
212            .deny(plain_text("baz"))
213            .build()
214            .unwrap_err();
215        assert_eq!(err.object(), "ConfirmationDialog");
216
217        let confirm_err = err.field("confirm");
218        assert!(confirm_err.includes(ValidationErrorKind::Required));
219    }
220
221    #[test]
222    fn it_requires_confirm_field_less_than_30_characters() {
223        let err = ConfirmationDialog::builder()
224            .title(plain_text("foo"))
225            .text(plain_text("bar"))
226            .confirm(plain_text("a".repeat(31)))
227            .deny(plain_text("baz"))
228            .build()
229            .unwrap_err();
230        assert_eq!(err.object(), "ConfirmationDialog");
231
232        let confirm_err = err.field("confirm");
233        assert!(confirm_err.includes(ValidationErrorKind::MaxTextLength(30)));
234    }
235
236    #[test]
237    fn it_requires_deny_field() {
238        let err = ConfirmationDialog::builder()
239            .title(plain_text("foo"))
240            .text(plain_text("bar"))
241            .confirm(plain_text("baz"))
242            .build()
243            .unwrap_err();
244        assert_eq!(err.object(), "ConfirmationDialog");
245
246        let deny_err = err.field("deny");
247        assert!(deny_err.includes(ValidationErrorKind::Required));
248    }
249
250    #[test]
251    fn it_requires_deny_field_less_than_30_characters() {
252        let err = ConfirmationDialog::builder()
253            .title(plain_text("foo"))
254            .text(plain_text("bar"))
255            .confirm(plain_text("baz"))
256            .deny(plain_text("a".repeat(31)))
257            .build()
258            .unwrap_err();
259        assert_eq!(err.object(), "ConfirmationDialog");
260
261        let deny_err = err.field("deny");
262        assert!(deny_err.includes(ValidationErrorKind::MaxTextLength(30)));
263    }
264}