1use async_trait::async_trait;
2use stoat_models::v0::{
3 BanListResult, Channel, DataCreateRole, DataCreateServerChannel, DataEditRoleRanks, Emoji,
4 Invite, Member, Role, Server,
5};
6use stoat_permissions::DataPermissionsValue;
7
8use crate::{HttpClient, Identifiable, Result, builders::EditServerBuilder};
9
10#[async_trait]
11pub trait ServerExt {
12 #[cfg(feature = "voice")]
13 fn voice_clients(&self, cache: impl AsRef<crate::GlobalCache>) -> Vec<crate::VoiceConnection>;
14
15 async fn fetch_member(
16 &self,
17 http: impl AsRef<HttpClient> + Send,
18 user_id: &str,
19 ) -> Result<Member>;
20 async fn fetch_bans(&self, http: impl AsRef<HttpClient> + Send) -> Result<BanListResult>;
21 async fn unban_member(&self, http: impl AsRef<HttpClient> + Send, user_id: &str) -> Result<()>;
22 async fn create_channel(
23 &mut self,
24 http: impl AsRef<HttpClient> + Send,
25 data: &DataCreateServerChannel,
26 ) -> Result<Channel>;
27 async fn fetch_emojis(&self, http: impl AsRef<HttpClient> + Send) -> Result<Vec<Emoji>>;
28 async fn fetch_invites(&self, http: impl AsRef<HttpClient> + Send) -> Result<Vec<Invite>>;
29 async fn set_default_permissions(
30 &mut self,
31 http: impl AsRef<HttpClient> + Send,
32 permissions: u64,
33 ) -> Result<()>;
34 async fn create_role(
35 &mut self,
36 http: impl AsRef<HttpClient> + Send,
37 name: String,
38 ) -> Result<Role>;
39 async fn reorder_roles(
40 &mut self,
41 http: impl AsRef<HttpClient> + Send,
42 order: Vec<Role>,
43 ) -> Result<()>;
44 async fn fetch_role(&self, http: impl AsRef<HttpClient> + Send, role_id: &str) -> Result<Role>;
45 async fn edit_server(&self, http: impl AsRef<HttpClient> + Send) -> EditServerBuilder;
46}
47
48#[async_trait]
49impl ServerExt for Server {
50 #[cfg(feature = "voice")]
51 fn voice_clients(&self, cache: impl AsRef<crate::GlobalCache>) -> Vec<crate::VoiceConnection> {
52 self.channels
53 .iter()
54 .filter_map(|id| cache.as_ref().get_voice_connection(id))
55 .collect()
56 }
57
58 async fn fetch_member(
59 &self,
60 http: impl AsRef<HttpClient> + Send,
61 user_id: &str,
62 ) -> Result<Member> {
63 http.as_ref().fetch_member(&self.id, user_id).await
64 }
65
66 async fn fetch_bans(&self, http: impl AsRef<HttpClient> + Send) -> Result<BanListResult> {
67 http.as_ref().fetch_bans(&self.id).await
68 }
69
70 async fn unban_member(&self, http: impl AsRef<HttpClient> + Send, user_id: &str) -> Result<()> {
71 http.as_ref().unban_member(&self.id, user_id).await
72 }
73
74 async fn create_channel(
75 &mut self,
76 http: impl AsRef<HttpClient> + Send,
77 data: &DataCreateServerChannel,
78 ) -> Result<Channel> {
79 let channel = http.as_ref().create_channel(&self.id, data).await?;
80
81 self.channels.push(channel.id().to_string());
82
83 Ok(channel)
84 }
85
86 async fn fetch_emojis(&self, http: impl AsRef<HttpClient> + Send) -> Result<Vec<Emoji>> {
87 http.as_ref().fetch_emojis(&self.id).await
88 }
89
90 async fn fetch_invites(&self, http: impl AsRef<HttpClient> + Send) -> Result<Vec<Invite>> {
91 http.as_ref().fetch_invites(&self.id).await
92 }
93
94 async fn set_default_permissions(
95 &mut self,
96 http: impl AsRef<HttpClient> + Send,
97 permissions: u64,
98 ) -> Result<()> {
99 let server = http
100 .as_ref()
101 .set_default_server_permissions(&self.id, &DataPermissionsValue { permissions })
102 .await?;
103
104 *self = server;
105
106 Ok(())
107 }
108
109 async fn create_role(
110 &mut self,
111 http: impl AsRef<HttpClient> + Send,
112 name: String,
113 ) -> Result<Role> {
114 let role = http
115 .as_ref()
116 .create_role(&self.id, &DataCreateRole { name, rank: None })
117 .await?;
118
119 self.roles.insert(role.id, role.role.clone());
120
121 Ok(role.role)
122 }
123
124 async fn reorder_roles(
125 &mut self,
126 http: impl AsRef<HttpClient> + Send,
127 order: Vec<Role>,
128 ) -> Result<()> {
129 let server = http
130 .as_ref()
131 .edit_role_positions(
132 &self.id,
133 &DataEditRoleRanks {
134 ranks: order.into_iter().map(|r| r.id).collect(),
135 },
136 )
137 .await?;
138
139 *self = server;
140
141 Ok(())
142 }
143
144 async fn fetch_role(&self, http: impl AsRef<HttpClient> + Send, role_id: &str) -> Result<Role> {
145 http.as_ref().fetch_role(&self.id, role_id).await
146 }
147
148 async fn edit_server(&self, http: impl AsRef<HttpClient> + Send) -> EditServerBuilder {
149 EditServerBuilder::new(http.as_ref().clone(), self.id.clone())
150 }
151}
152
153impl Identifiable for Server {
154 fn id(&self) -> &str {
155 &self.id
156 }
157}