Skip to main content

slack_messaging/blocks/
mod.rs

1use serde::Serialize;
2
3/// Builders for blocks.
4pub mod builders;
5/// Objects from which blocks are composed.
6pub mod elements;
7/// Module for building [RichText] block.
8pub mod rich_text;
9/// Module for building [Table] block.
10pub mod table;
11/// Module for building [DataTable] block.
12pub mod data_table;
13
14mod actions;
15mod alert;
16mod card;
17mod carousel;
18mod context;
19mod context_actions;
20mod divider;
21mod file;
22mod header;
23mod image;
24mod input;
25mod markdown;
26mod plan;
27mod section;
28mod task_card;
29mod video;
30
31pub use actions::{Actions, ActionsElement};
32pub use alert::{Alert, AlertLevel};
33pub use card::Card;
34pub use carousel::Carousel;
35pub use context::{Context, ContextElement};
36pub use context_actions::{ContextActions, ContextActionsElement};
37pub use data_table::DataTable;
38pub use divider::Divider;
39pub use file::{File, FileSource};
40pub use header::Header;
41pub use image::Image;
42pub use input::{Input, InputElement};
43pub use markdown::Markdown;
44pub use plan::Plan;
45pub use rich_text::RichText;
46pub use section::{Accessory, Section};
47pub use table::Table;
48pub use task_card::{TaskCard, TaskStatus};
49pub use video::Video;
50
51/// Objects that can be set to blocks in [Message](crate::message::Message).
52#[derive(Debug, Clone, Serialize, PartialEq)]
53#[serde(untagged)]
54pub enum Block {
55    /// [Actions block](https://docs.slack.dev/reference/block-kit/blocks/actions-block) representation
56    Actions(Box<Actions>),
57
58    /// [Alert block](https://docs.slack.dev/reference/block-kit/blocks/alert-block) representation
59    Alert(Box<Alert>),
60
61    /// [Card block](https://docs.slack.dev/reference/block-kit/blocks/card-block)
62    /// representation
63    Card(Box<Card>),
64
65    /// [Carousel block](https://docs.slack.dev/reference/block-kit/blocks/carousel-block)
66    /// representation
67    Carousel(Box<Carousel>),
68
69    /// [Context block](https://docs.slack.dev/reference/block-kit/blocks/context-block) representation
70    Context(Box<Context>),
71
72    /// [Context actions block](https://docs.slack.dev/reference/block-kit/blocks/context-actions-block) representation
73    ContextActions(Box<ContextActions>),
74
75    /// [Data table block](https://docs.slack.dev/reference/block-kit/blocks/data-table-block) representation
76    DataTable(Box<DataTable>),
77
78    /// [Divider block](https://docs.slack.dev/reference/block-kit/blocks/divider-block) representation
79    Divider(Box<Divider>),
80
81    /// [File block](https://docs.slack.dev/reference/block-kit/blocks/file-block) representation
82    File(Box<File>),
83
84    /// [Header block](https://docs.slack.dev/reference/block-kit/blocks/header-block) representation
85    Header(Box<Header>),
86
87    /// [Image block](https://docs.slack.dev/reference/block-kit/blocks/image-block) representation
88    Image(Box<Image>),
89
90    /// [Input block](https://docs.slack.dev/reference/block-kit/blocks/input-block) representation
91    Input(Box<Input>),
92
93    /// [Markdown block](https://docs.slack.dev/reference/block-kit/blocks/markdown-block) representation
94    Markdown(Box<Markdown>),
95
96    /// [Plan block](https://docs.slack.dev/reference/block-kit/blocks/plan-block) representation
97    Plan(Box<Plan>),
98
99    /// [Rich text block](https://docs.slack.dev/reference/block-kit/blocks/rich-text-block) representation
100    RichText(Box<RichText>),
101
102    /// [Section block](https://docs.slack.dev/reference/block-kit/blocks/section-block) representation
103    Section(Box<Section>),
104
105    /// [Table block](https://docs.slack.dev/reference/block-kit/blocks/table-block) representation
106    Table(Box<Table>),
107
108    /// [Task card block](https://docs.slack.dev/reference/block-kit/blocks/task-card-block)
109    /// representation
110    TaskCard(Box<TaskCard>),
111
112    /// [Video block](https://docs.slack.dev/reference/block-kit/blocks/video-block) representation
113    Video(Box<Video>),
114}
115
116macro_rules! block_from {
117    ($($ty:ident,)*) => {
118        $(
119            impl From<$ty> for Block {
120                fn from(value: $ty) -> Self {
121                    Self::$ty(Box::new(value))
122                }
123            }
124         )*
125    }
126}
127
128block_from! {
129    Actions,
130    Alert,
131    Card,
132    Carousel,
133    Context,
134    ContextActions,
135    DataTable,
136    Divider,
137    File,
138    Header,
139    Image,
140    Input,
141    Markdown,
142    Plan,
143    RichText,
144    Section,
145    Table,
146    TaskCard,
147    Video,
148}
149
150#[cfg(test)]
151pub mod test_helpers {
152    use super::rich_text::test_helpers as rich_text_helper;
153    use super::rich_text::types::test_helpers::*;
154    use super::*;
155    use crate::composition_objects::test_helpers::*;
156
157    pub fn header(text: impl Into<String>) -> Header {
158        Header {
159            block_id: None,
160            text: Some(plain_text(text)),
161        }
162    }
163
164    pub fn section(text: impl Into<String>) -> Section {
165        Section {
166            block_id: None,
167            text: Some(mrkdwn_text(text).into()),
168            fields: None,
169            accessory: None,
170            expand: None,
171        }
172    }
173
174    pub fn rich_text() -> RichText {
175        RichText {
176            block_id: Some("rich_text_0".into()),
177            elements: Some(vec![rich_text_helper::section(vec![el_text("foo")]).into()]),
178        }
179    }
180
181    pub fn task_card() -> TaskCard {
182        TaskCard {
183            task_id: Some("task_0".into()),
184            title: Some("Fetching weather data".into()),
185            status: Some(TaskStatus::Pending),
186            output: None,
187            details: None,
188            sources: None,
189            block_id: None,
190        }
191    }
192}