1use crate::builders::create_message::CreateMessage;
2use crate::builders::edit_channel::EditChannel;
3use crate::builders::fetch_messages::FetchMessagesBuilder;
4use crate::context::Context;
5use crate::model::message::Message;
6use serde::{Deserialize, Serialize};
7use std::fmt;
8use crate::error::Error;
9use crate::http::HttpError;
10use crate::http::routing::Route;
11use crate::model::invite::Invite;
12use crate::model::permissions::Permissions;
13use crate::model::traits::{Nameable, ServerId};
14
15#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Default)]
17#[serde(transparent)]
18pub struct ChannelId(pub String);
19
20impl ChannelId {
21 pub async fn send_message(&self, ctx: &Context, builder: CreateMessage) -> Result<Message, HttpError> {
23 builder.execute(&ctx.http, self).await
24 }
25
26 pub fn fetch_messages<'a>(&self, ctx: &'a Context) -> FetchMessagesBuilder<'a> {
28 FetchMessagesBuilder {
29 channel_id: self.0.clone(),
30 limit: None,
31 before: None,
32 after: None,
33 sort: None,
34 nearby: None,
35 include_users: None,
36 ctx,
37 }
38 }
39 pub async fn get(&self, ctx: &Context) -> Option<Channel> {
42 ctx.cache.channels.get(&self.0).await
43 }
44 pub async fn fetch(&self, ctx: &Context, force: Option<bool>) -> Result<Channel, HttpError> {
47 if !force.unwrap_or(false) {
48 if let Some(channel) = ctx.cache.channels.get(&self.0).await {
49 return Ok(channel);
50 }
51 }
52 let route = Route::GetChannel { channel_id: &self.0 };
53 let channel = ctx.http.get::<Channel>(route).await?;
54
55 ctx.cache.channels.insert(self.0.clone(), channel.clone()).await;
56
57 Ok(channel)
58 }
59 pub async fn delete(&self, ctx: &Context, leave_silent: Option<bool>) -> Result<(), HttpError> {
64 #[derive(Serialize, Deserialize)]
65 struct CloseQuery {
66 leave_silently: bool,
67 }
68 let route = Route::DeleteChannel { channel_id: &self.0 };
69 let query = CloseQuery {
70 leave_silently: leave_silent.unwrap_or(false),
71 };
72 ctx.http.request::<(), CloseQuery, ()>(route, None, Some(&query)).await
73 }
74 pub async fn edit(&self, ctx: &Context, builder: EditChannel) -> Result<Channel, HttpError> {
75 builder.execute(&ctx.http, self).await
76 }
77 pub async fn to_channel(&self, ctx: &Context) -> Option<Channel> {
81 ctx.cache.channels.get(&self.0).await
82 }
83 pub async fn create_invite(&self, ctx: &Context) -> Result<Invite, HttpError> {
84 let route = Route::CreateInvite { channel_id: &self.0 };
85 ctx.http.request::<(), (), Invite>(route, None, None).await
86 }
87}
88
89impl fmt::Display for ChannelId {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 write!(f, "{}", self.0)
92 }
93}
94
95impl From<&str> for ChannelId {
96 fn from(s: &str) -> Self {
97 Self(s.to_string())
98 }
99}
100impl From<String> for ChannelId {
101 fn from(s: String) -> Self {
102 Self(s)
103 }
104}
105
106#[derive(Debug, Clone, Deserialize, Serialize)]
107#[serde(tag = "channel_type")]
108pub enum ChannelKind {
109 SavedMessages(SavedMessages),
110 DirectMessage(DirectMessage),
111 Group(Group),
112 TextChannel(TextChannel),
113 VoiceChannel(VoiceChannel),
114
115 #[serde(other)]
116 Unknown,
117}
118#[derive(Debug, Clone, Deserialize, Serialize)]
119pub struct Channel {
120 #[serde(rename = "_id")]
121 pub id: ChannelId,
122
123 #[serde(flatten)]
124 pub kind: ChannelKind,
125}
126impl Channel {
127 pub async fn send_message(&self, ctx: &Context, builder: CreateMessage) -> Result<Message, HttpError> {
128 self.id.send_message(ctx, builder).await
129 }
130 pub fn as_text(&self) -> Option<&TextChannel> {
142 match &self.kind {
143 ChannelKind::TextChannel(c) => Some(c), _ => None,
145 }
146 }
147
148 pub fn as_voice(&self) -> Option<&VoiceChannel> {
149 match &self.kind {
150 ChannelKind::VoiceChannel(c) => Some(c),
151 _ => None,
152 }
153 }
154
155 pub fn as_group(&self) -> Option<&Group> {
156 match &self.kind {
157 ChannelKind::Group(c) => Some(c),
158 _ => None,
159 }
160 }
161
162 pub fn as_dm(&self) -> Option<&DirectMessage> {
163 match &self.kind {
164 ChannelKind::DirectMessage(c) => Some(c),
165 _ => None,
166 }
167 }
168 pub async fn create_invite(&self, ctx: &Context) -> Result<Invite, Error> {
169 let is_allowed = matches!(
171 self.kind,
172 ChannelKind::TextChannel(_) | ChannelKind::Group(_)
173 );
174
175 if !is_allowed {
176 return Err(Error::InvalidChannelType(
177 "Invites can only be created for Text Channels or Groups".into()
178 ));
179 }
180
181 self.id.create_invite(ctx).await.map_err(Error::from)
183 }
184}
185impl Nameable for Channel {
186 fn name(&self) -> Option<&str> {
187 match &self.kind {
188 ChannelKind::TextChannel(c) => Some(&c.name),
189 ChannelKind::Group(c) => Some(&c.name),
190 ChannelKind::VoiceChannel(c) => Some(&c.name),
191 _ => None,
192 }
193 }
194}
195impl ServerId for Channel {
196 fn server_id(&self) -> Option<&str> {
197 match &self.kind {
198 ChannelKind::TextChannel(c) => Some(&c.server),
199 ChannelKind::VoiceChannel(c) => Some(&c.server),
200 _ => None,
201 }
202 }
203}
204#[derive(Debug, Clone, Deserialize, Serialize)]
205pub struct SavedMessages {
206 pub user: String,
207}
208
209#[derive(Debug, Clone, Deserialize, Serialize)]
210pub struct DirectMessage {
211 pub active: bool,
212 pub recipients: Vec<String>,
213 pub last_message: Option<Message>,
214}
215
216#[derive(Debug, Clone, Deserialize, Serialize)]
217pub struct Group {
218 pub name: String,
219 pub owner: String,
220 pub recipients: Vec<String>,
221 pub permissions: Option<Permissions>,
222 pub nsfw: Option<bool>,
223}
224
225#[derive(Debug, Clone, Deserialize, Serialize)]
226pub struct TextChannel {
227 pub server: String,
228 pub name: String,
229 pub description: Option<String>,
230 pub last_message_id: Option<String>,
231 #[serde(default)]
232 pub nsfw: bool,
233}
234
235#[derive(Debug, Clone, Deserialize, Serialize)]
236pub struct VoiceChannel {
237 pub server: String,
238 pub name: String,
239 pub description: Option<String>,
240}