Skip to main content

mutiny_rs/model/
message.rs

1//! Model relating to Stoat channels
2
3use crate::builders::create_embed::SendableEmbed;
4use crate::builders::edit_message::EditMessageBuilder;
5use crate::context::Context;
6use crate::http::HttpError;
7use crate::model::channel::{ChannelId};
8use crate::model::ready::Member;
9use crate::model::user::User;
10use serde::{Deserialize, Serialize};
11use crate::builders::create_message::CreateMessage;
12use crate::http::routing::Route;
13
14#[derive(Serialize, Default, Debug, Clone)]
15pub struct SendMessageBody {
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub content: Option<String>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub nonce: Option<String>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub attachments: Option<Vec<String>>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub replies: Option<Vec<Replies>>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub embeds: Option<Vec<SendableEmbed>>,
26}
27#[derive(Debug, Serialize, Clone, PartialEq)]
28pub enum Sort {
29    Relevance,
30    Latest,
31    Oldest,
32}
33
34#[derive(Debug, Serialize, Default, Clone)]
35pub struct FetchMessagesQuery {
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub limit: Option<usize>,
38
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub before: Option<String>,
41
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub after: Option<String>,
44
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub sort: Option<Sort>,
47
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub nearby: Option<String>,
50
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub include_users: Option<bool>,
53}
54#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
55pub enum MessageSort {
56    Relevance,
57    Latest,
58    Oldest,
59}
60
61#[derive(Debug, Serialize, Default, Clone)]
62pub struct SearchMessagesBody {
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub query: Option<String>,
65
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub limit: Option<usize>,
68
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub before: Option<String>,
71
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub after: Option<String>,
74
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub sort: Option<MessageSort>,
77
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub include_users: Option<bool>,
80
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub pinned: Option<bool>,
83}
84
85#[derive(Debug, Deserialize)]
86pub struct SearchResponse {
87    pub messages: Vec<Message>,
88    #[serde(default)]
89    pub users: Vec<User>,
90    #[serde(default)]
91    pub members: Vec<Member>,
92}
93
94#[derive(Debug, Serialize, Deserialize, Clone)]
95pub struct Message {
96    #[serde(rename = "_id")]
97    pub id: String,
98    pub nonce: Option<String>,
99    pub channel: ChannelId,
100    pub author: String,
101    pub user: Option<User>,
102    pub member: Option<Member>,
103    pub content: Option<String>,
104    pub mentions: Option<Vec<String>>,
105    pub attachments: Option<Vec<MessageAttachments>>,
106    pub edited: Option<String>
107}
108
109#[derive(Debug, Serialize, Deserialize, Clone)]
110pub struct MessageAttachments {
111    #[serde(rename = "_id")]
112    pub id: String,
113    pub tag: String,
114    pub filename: String,
115    pub metadata: MessageMetadata,
116    pub content_type: String,
117    pub size: usize
118}
119
120#[derive(Debug, Serialize, Deserialize, Clone)]
121pub struct MessageMetadata {
122    #[serde(rename = "type")]
123    pub _type: String,
124    pub width: usize,
125    pub height: usize,
126}
127
128#[derive(Debug, Serialize, Deserialize, Clone, Default)]
129pub struct Replies {
130    pub id: String,
131    pub mention: bool,
132    pub fail_if_not_exists: Option<bool>,
133}
134impl Replies {
135    pub fn new(message_id: String) -> Self {
136        Self {
137            id: message_id,
138            mention: true, // Default to true
139            fail_if_not_exists: Some(false),
140        }
141    }
142}
143impl Message {
144    /// Reply to the message object
145    pub async fn reply(&self, ctx: &Context, builder: CreateMessage) -> Result<Message, HttpError> {
146        let builder = builder.replies(Replies::new(self.id.clone()));
147        self.channel.send_message(ctx, builder).await
148    }
149    pub async fn pin(&self, ctx: &Context) -> Result<(), HttpError> {
150        let route = Route::MessagePin { channel_id: &self.channel.0, message_id: &self.id };
151        ctx.http.request::<(), (), ()>(route, None, None).await
152    }
153    pub async fn unpin(&self, ctx: &Context) -> Result<(), HttpError> {
154        let route = Route::MessageUnpin { channel_id: &self.channel.0, message_id: &self.id };
155        ctx.http.request::<(), (), ()>(route, None, None).await
156    }
157    pub async fn delete(&self, ctx: &Context) -> Result<(), HttpError> {
158        let route = Route::MessageDelete { channel_id: &self.channel.0, message_id: &self.id };
159        ctx.cache.messages.remove(&self.id).await;
160        ctx.http.request::<(), (), ()>(route, None, None).await
161    }
162    pub fn edit<'a>(&'a self, ctx: &'a Context) -> EditMessageBuilder<'a> {
163        EditMessageBuilder {
164            message: self,
165            ctx,
166            content: None,
167            embeds: None,
168        }
169    }
170}