titanium_model/builder/
interaction.rs

1use crate::builder::component::ActionRowBuilder;
2use crate::TitanString;
3
4/// Builder for creating a Modal.
5#[derive(Debug, Clone)]
6#[must_use]
7pub struct ModalBuilder<'a> {
8    custom_id: TitanString<'a>,
9    title: TitanString<'a>,
10    components: Vec<crate::Component<'a>>,
11}
12
13impl<'a> ModalBuilder<'a> {
14    pub fn new(custom_id: impl Into<TitanString<'a>>, title: impl Into<TitanString<'a>>) -> Self {
15        Self {
16            custom_id: custom_id.into(),
17            title: title.into(),
18            components: Vec::new(),
19        }
20    }
21
22    pub fn row(mut self, row: ActionRowBuilder<'a>) -> Self {
23        self.components.push(row.build());
24        self
25    }
26
27    #[must_use]
28    pub fn build(self) -> crate::interaction::Modal<'a> {
29        crate::interaction::Modal {
30            custom_id: self.custom_id,
31            title: self.title,
32            components: self.components,
33        }
34    }
35}
36
37/// Builder for Interaction Response.
38#[derive(Debug, Clone)]
39#[must_use]
40pub struct InteractionResponseBuilder<'a> {
41    response: crate::interaction::InteractionResponse<'a>,
42}
43
44impl Default for InteractionResponseBuilder<'_> {
45    fn default() -> Self {
46        Self::new()
47    }
48}
49
50impl<'a> InteractionResponseBuilder<'a> {
51    /// Create a new builder.
52    pub fn new() -> Self {
53        Self {
54            response: crate::interaction::InteractionResponse {
55                response_type:
56                    crate::interaction::InteractionCallbackType::ChannelMessageWithSource,
57                data: Some(Default::default()),
58            },
59        }
60    }
61
62    pub fn kind(mut self, kind: crate::interaction::InteractionCallbackType) -> Self {
63        self.response.response_type = kind;
64        self
65    }
66
67    pub fn content(mut self, content: impl Into<TitanString<'a>>) -> Self {
68        if let Some(data) = &mut self.response.data {
69            data.content = Some(content.into());
70        }
71        self
72    }
73
74    pub fn embed(mut self, embed: impl Into<crate::Embed<'a>>) -> Self {
75        if self.response.data.is_none() {
76            self.response.data = Some(Default::default());
77        }
78        if let Some(data) = &mut self.response.data {
79            data.embeds.push(embed.into());
80        }
81        self
82    }
83
84    pub fn component(mut self, component: impl Into<crate::Component<'a>>) -> Self {
85        if self.response.data.is_none() {
86            self.response.data = Some(Default::default());
87        }
88        if let Some(data) = &mut self.response.data {
89            data.components.push(component.into());
90        }
91        self
92    }
93
94    pub fn components(mut self, components: Vec<crate::Component<'a>>) -> Self {
95        if self.response.data.is_none() {
96            self.response.data = Some(Default::default());
97        }
98        if let Some(data) = &mut self.response.data {
99            data.components.extend(components);
100        }
101        self
102    }
103
104    pub fn ephemeral(mut self, ephemeral: bool) -> Self {
105        if ephemeral {
106            if self.response.data.is_none() {
107                self.response.data = Some(Default::default());
108            }
109            if let Some(data) = &mut self.response.data {
110                data.flags = Some(64);
111            }
112        }
113        self
114    }
115
116    /// Sets response type to DeferredChannelMessageWithSource (5)
117    pub fn deferred(mut self, ephemeral: bool) -> Self {
118        self.response.response_type =
119            crate::interaction::InteractionCallbackType::DeferredChannelMessageWithSource;
120        if ephemeral {
121            self = self.ephemeral(true);
122        }
123        self
124    }
125
126    /// Sets response type to UpdateMessage (7) - for component interactions
127    pub fn update_message(mut self) -> Self {
128        self.response.response_type = crate::interaction::InteractionCallbackType::UpdateMessage;
129        self
130    }
131
132    #[must_use]
133    pub fn build(self) -> crate::interaction::InteractionResponse<'a> {
134        self.response
135    }
136
137    pub fn modal(mut self, modal: crate::interaction::Modal<'a>) -> Self {
138        self.response.response_type = crate::interaction::InteractionCallbackType::Modal;
139        self.response.data = Some(crate::interaction::InteractionCallbackData {
140            custom_id: Some(modal.custom_id),
141            title: Some(modal.title),
142            components: modal.components,
143            ..Default::default()
144        });
145        self
146    }
147}
148
149impl<'a> From<InteractionResponseBuilder<'a>> for crate::interaction::InteractionResponse<'a> {
150    fn from(builder: InteractionResponseBuilder<'a>) -> Self {
151        builder.build()
152    }
153}