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