titanium_model/
create_message.rs

1use crate::{Component, Embed};
2
3use crate::TitanString;
4use serde::{Deserialize, Serialize};
5
6// ============================================================================
7// File Upload (merged from file.rs)
8// ============================================================================
9
10/// A file to be uploaded to Discord.
11#[derive(Debug, Clone)]
12pub struct FileUpload {
13    /// The name of the file.
14    pub filename: String,
15    /// The binary data of the file.
16    pub data: Vec<u8>,
17}
18
19impl FileUpload {
20    /// Create a new `FileUpload`.
21    pub fn new(filename: impl Into<String>, data: impl Into<Vec<u8>>) -> Self {
22        Self {
23            filename: filename.into(),
24            data: data.into(),
25        }
26    }
27}
28
29// ============================================================================
30// Create Message
31// ============================================================================
32
33/// Payload to create a message.
34#[derive(Debug, Clone, Serialize, Deserialize, Default)]
35pub struct CreateMessage<'a> {
36    /// Message content.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub content: Option<TitanString<'a>>,
39
40    /// Pass true if sending a TTS message.
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub tts: Option<bool>,
43
44    /// Embeds to include.
45    #[serde(skip_serializing_if = "Option::is_none", borrow)]
46    pub embeds: Option<Vec<Embed<'a>>>,
47
48    /// Components to include.
49    #[serde(skip_serializing_if = "Option::is_none", borrow)]
50    pub components: Option<Vec<Component<'a>>>,
51
52    /// Message flags (`SUPPRESS_EMBEDS`, `SUPPRESS_NOTIFICATIONS`).
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub flags: Option<u64>,
55
56    /// Message reference (reply).
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub message_reference: Option<crate::MessageReference>,
59
60    /// Files to upload (not serialized to JSON, used by HTTP client).
61    #[serde(skip)]
62    pub files: Vec<FileUpload>,
63}
64
65impl<'a> CreateMessage<'a> {
66    /// Create a simple text message.
67    pub fn new(content: impl Into<String>) -> Self {
68        Self {
69            content: Some(content.into().into()),
70            ..Default::default()
71        }
72    }
73
74    /// Add an embed.
75    #[must_use]
76    pub fn embed(mut self, embed: Embed<'a>) -> Self {
77        if let Some(embeds) = &mut self.embeds {
78            embeds.push(embed);
79        } else {
80            self.embeds = Some(vec![embed]);
81        }
82        self
83    }
84
85    /// Add a component.
86    #[must_use]
87    pub fn component(mut self, component: Component<'a>) -> Self {
88        if let Some(components) = &mut self.components {
89            components.push(component);
90        } else {
91            self.components = Some(vec![component]);
92        }
93        self
94    }
95}