Skip to main content

slack_blocks_render/
visitor.rs

1use despatma::visitor;
2use slack_morphism::prelude::*;
3
4pub(crate) struct SlackEventBlock {
5    #[allow(dead_code)]
6    pub json_value: serde_json::Value,
7}
8
9pub(crate) struct SlackRichTextBlock {
10    pub json_value: serde_json::Value,
11}
12
13visitor!(
14    #[
15        helper_tmpl = {
16            match slack_block {
17                SlackBlock::Section(section) => visitor.visit_slack_section_block(section),
18                SlackBlock::Header(header) => visitor.visit_slack_header_block(header),
19                SlackBlock::Divider(divider) => visitor.visit_slack_divider_block(divider),
20                SlackBlock::Image(image) => visitor.visit_slack_image_block(image),
21                SlackBlock::Actions(actions) => visitor.visit_slack_actions_block(actions),
22                SlackBlock::Context(context) => visitor.visit_slack_context_block(context),
23                SlackBlock::Input(input) => visitor.visit_slack_input_block(input),
24                SlackBlock::File(file) => visitor.visit_slack_file_block(file),
25                SlackBlock::Video(video) => visitor.visit_slack_video_block(video),
26                SlackBlock::RichText(rich_text_block) => visitor.visit_slack_rich_text_block(&SlackRichTextBlock { json_value: serde_json::to_value(rich_text_block).unwrap_or_default() }),
27                SlackBlock::Event(json_value) => visitor.visit_slack_event_block(&SlackEventBlock { json_value: json_value.clone() }),
28                SlackBlock::Markdown(markdown) => visitor.visit_slack_markdown_block(markdown),
29                SlackBlock::ShareShortcut(_) => {},
30                // Alert blocks (added in slack-morphism 2.23) carry a single text field.
31                SlackBlock::Alert(alert) => visitor.visit_slack_block_text(&alert.text),
32                // Table and TaskCard blocks (added in slack-morphism 2.22), Card, Carousel
33                // and ContextActions blocks (added in 2.23) carry no plain-text/markdown
34                // representation we can render, so emit nothing.
35                SlackBlock::Table(_)
36                | SlackBlock::TaskCard(_)
37                | SlackBlock::Card(_)
38                | SlackBlock::Carousel(_)
39                | SlackBlock::ContextActions(_) => {}
40                // Container blocks (added in slack-morphism 2.30) wrap other blocks:
41                // render their children so the content they hold is not lost.
42                SlackBlock::Container(container) => {
43                    for child_block in &container.child_blocks {
44                        visitor.visit_slack_block(child_block);
45                    }
46                }
47                // Plan, DataTable and DataVisualization blocks (added in 2.30) carry no
48                // plain-text/markdown representation we can render, and Unknown keeps any
49                // block type slack-morphism does not model as raw JSON, so emit nothing.
50                SlackBlock::Plan(_)
51                | SlackBlock::DataTable(_)
52                | SlackBlock::DataVisualization(_)
53                | SlackBlock::Unknown(_) => {}
54            }
55        },
56    ]
57    SlackBlock,
58    #[
59        helper_tmpl = {
60            if let Some(text) = &slack_section_block.text {
61                visitor.visit_slack_block_text(text);
62            }
63            if let Some(fields) = &slack_section_block.fields {
64                for field in fields {
65                    visitor.visit_slack_block_text(field);
66                }
67            }
68        },
69    ]
70    SlackSectionBlock,
71    #[
72        helper_tmpl = {
73            match slack_block_text {
74                SlackBlockText::Plain(plain) => visitor.visit_slack_block_plain_text(plain),
75                SlackBlockText::MarkDown(markdown) => visitor.visit_slack_block_mark_down_text(markdown),
76            }
77        },
78    ]
79    SlackBlockText,
80    SlackBlockPlainText,
81    #[
82        helper_tmpl = {
83            let slack_block_text = slack_header_block.text.clone().into();
84            visitor.visit_slack_block_text(&slack_block_text);
85        },
86    ]
87    SlackHeaderBlock,
88    SlackDividerBlock,
89    SlackImageBlock,
90    SlackBlockImageElement,
91    SlackActionsBlock,
92    #[
93        helper_tmpl = {
94            for element in &slack_context_block.elements {
95                match element {
96                    SlackContextBlockElement::Image(image) => visitor.visit_slack_block_image_element(image),
97                    SlackContextBlockElement::Plain(text) => visitor.visit_slack_block_plain_text(text),
98                    SlackContextBlockElement::MarkDown(markdown) => visitor.visit_slack_block_mark_down_text(markdown),
99                }
100            }
101        },
102    ]
103    SlackContextBlock,
104    SlackBlockMarkDownText,
105    SlackInputBlock,
106    SlackFileBlock,
107    SlackVideoBlock,
108    SlackEventBlock,
109    SlackRichTextBlock,
110    SlackMarkdownBlock,
111);