Skip to main content

chat_system/
message.rs

1//! Core message types.
2
3use serde::{Deserialize, Serialize};
4
5/// The kind of a message, allowing callers to distinguish between regular
6/// text messages and system events.
7#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum MessageType {
10    /// A regular text message.
11    #[default]
12    Text,
13    /// A system/service message (join, leave, topic change, etc.).
14    System,
15    /// The message was edited (content reflects the latest version).
16    Edit,
17    /// The message was deleted (content may be empty).
18    Delete,
19    /// The message contains a media attachment (image, file, etc.).
20    Media,
21    /// An action / `/me` message (IRC ACTION, Slack `/me`).
22    Action,
23}
24
25/// A single emoji reaction attached to a message, with an aggregate count and
26/// the list of user IDs who reacted.
27///
28/// `user_ids` may be empty on platforms that only expose aggregate counts.
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
30pub struct Reaction {
31    /// The emoji (Unicode character or platform-specific shortcode).
32    pub emoji: String,
33    /// Number of users who added this reaction.
34    pub count: u32,
35    /// IDs of the users who reacted (may be empty if the platform does not expose them).
36    #[serde(default)]
37    pub user_ids: Vec<String>,
38}
39
40/// A message received from or sent to a chat platform.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct Message {
43    pub id: String,
44    pub sender: String,
45    pub content: String,
46    pub timestamp: i64,
47    #[serde(default)]
48    pub channel: Option<String>,
49    /// ID of the message this is replying to, if any.
50    #[serde(default)]
51    pub reply_to: Option<String>,
52    /// Thread / conversation ID, when the platform distinguishes threads from
53    /// the main channel timeline (e.g. Slack, Discord, Matrix).
54    #[serde(default)]
55    pub thread_id: Option<String>,
56    #[serde(default)]
57    pub media: Option<Vec<MediaAttachment>>,
58    #[serde(default)]
59    pub is_direct: bool,
60    /// The kind of this message.
61    #[serde(default)]
62    pub message_type: MessageType,
63    /// When the message was last edited (Unix timestamp), if applicable.
64    #[serde(default)]
65    pub edited_timestamp: Option<i64>,
66    /// Reactions attached to this message (populated when receiving messages on
67    /// platforms that expose them; `None` means unknown / not fetched).
68    #[serde(default)]
69    pub reactions: Option<Vec<Reaction>>,
70}
71
72/// A media attachment in a message.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct MediaAttachment {
75    pub url: Option<String>,
76    pub path: Option<String>,
77    pub mime_type: Option<String>,
78    pub filename: Option<String>,
79    /// File size in bytes, when known.
80    #[serde(default)]
81    pub size: Option<u64>,
82}
83
84/// Options for sending a message with additional metadata.
85#[derive(Debug, Default)]
86pub struct SendOptions<'a> {
87    pub recipient: &'a str,
88    pub content: &'a str,
89    pub reply_to: Option<&'a str>,
90    /// Thread ID to send into (platforms that support threading).
91    pub thread_id: Option<&'a str>,
92    pub silent: bool,
93    pub media: Option<&'a str>,
94}