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