1use diesel::{
2 ExpressionMethods, Insertable, QueryDsl, Queryable, Selectable, SelectableHelper, insert_into,
3 update,
4};
5use diesel_async::RunQueryDsl;
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9use crate::{error::Error, schema::{role_members, roles}, utils::order_by_is_above, Conn, Data};
10
11use super::{HasIsAbove, HasUuid, load_or_empty};
12
13#[derive(Deserialize, Serialize, Clone, Queryable, Selectable, Insertable)]
14#[diesel(table_name = roles)]
15#[diesel(check_for_backend(diesel::pg::Pg))]
16pub struct Role {
17 uuid: Uuid,
18 guild_uuid: Uuid,
19 name: String,
20 color: i32,
21 is_above: Option<Uuid>,
22 pub permissions: i64,
23}
24
25#[derive(Serialize, Clone, Queryable, Selectable, Insertable)]
26#[diesel(table_name = role_members)]
27#[diesel(check_for_backend(diesel::pg::Pg))]
28pub struct RoleMember {
29 role_uuid: Uuid,
30 member_uuid: Uuid,
31}
32
33impl RoleMember {
34 async fn fetch_role(&self, conn: &mut Conn) -> Result<Role, Error> {
35 use roles::dsl;
36 let role: Role = dsl::roles
37 .filter(dsl::uuid.eq(self.role_uuid))
38 .select(Role::as_select())
39 .get_result(conn)
40 .await?;
41
42 Ok(role)
43 }
44}
45
46impl HasUuid for Role {
47 fn uuid(&self) -> &Uuid {
48 self.uuid.as_ref()
49 }
50}
51
52impl HasIsAbove for Role {
53 fn is_above(&self) -> Option<&Uuid> {
54 self.is_above.as_ref()
55 }
56}
57
58impl Role {
59 pub async fn fetch_all(conn: &mut Conn, guild_uuid: Uuid) -> Result<Vec<Self>, Error> {
60 use roles::dsl;
61 let roles: Vec<Role> = load_or_empty(
62 dsl::roles
63 .filter(dsl::guild_uuid.eq(guild_uuid))
64 .select(Role::as_select())
65 .load(conn)
66 .await,
67 )?;
68
69 Ok(roles)
70 }
71
72 pub async fn fetch_from_member(data: &Data, member_uuid: Uuid) -> Result<Vec<Self>, Error> {
73 if let Ok(roles) = data.get_cache_key(format!("{}_roles", member_uuid)).await {
74 return Ok(serde_json::from_str(&roles)?)
75 }
76
77 let mut conn = data.pool.get().await?;
78
79 use role_members::dsl;
80 let role_memberships: Vec<RoleMember> = load_or_empty(
81 dsl::role_members
82 .filter(dsl::member_uuid.eq(member_uuid))
83 .select(RoleMember::as_select())
84 .load(&mut conn)
85 .await,
86 )?;
87
88 let mut roles = vec![];
89
90 for membership in role_memberships {
91 roles.push(membership.fetch_role(&mut conn).await?);
92 }
93
94 data.set_cache_key(format!("{}_roles", member_uuid), roles.clone(), 300).await?;
95
96 Ok(roles)
97 }
98
99 pub async fn fetch_one(conn: &mut Conn, role_uuid: Uuid) -> Result<Self, Error> {
100 use roles::dsl;
101 let role: Role = dsl::roles
102 .filter(dsl::uuid.eq(role_uuid))
103 .select(Role::as_select())
104 .get_result(conn)
105 .await?;
106
107 Ok(role)
108 }
109
110 pub async fn fetch_permissions(&self) -> Vec<Permissions> {
111 Permissions::fetch_permissions(self.permissions.clone())
112 }
113
114 pub async fn new(conn: &mut Conn, guild_uuid: Uuid, name: String) -> Result<Self, Error> {
115 let role_uuid = Uuid::now_v7();
116
117 let roles = Self::fetch_all(conn, guild_uuid).await?;
118
119 let roles_ordered = order_by_is_above(roles).await?;
120
121 let last_role = roles_ordered.last();
122
123 let new_role = Role {
124 uuid: role_uuid,
125 guild_uuid,
126 name,
127 color: 16777215,
128 is_above: None,
129 permissions: 0,
130 };
131
132 insert_into(roles::table)
133 .values(new_role.clone())
134 .execute(conn)
135 .await?;
136
137 if let Some(old_last_role) = last_role {
138 use roles::dsl;
139 update(roles::table)
140 .filter(dsl::uuid.eq(old_last_role.uuid))
141 .set(dsl::is_above.eq(new_role.uuid))
142 .execute(conn)
143 .await?;
144 }
145
146 Ok(new_role)
147 }
148}
149
150#[derive(Clone, Copy, PartialEq, Eq)]
151pub enum Permissions {
152 SendMessage = 1,
153 CreateChannel = 2,
154 DeleteChannel = 4,
155 ManageChannel = 8,
156 CreateRole = 16,
157 DeleteRole = 32,
158 ManageRole = 64,
159 CreateInvite = 128,
160 ManageInvite = 256,
161 ManageServer = 512,
162 ManageMember = 1024,
163}
164
165impl Permissions {
166 pub fn fetch_permissions(permissions: i64) -> Vec<Self> {
167 let all_perms = vec![
168 Self::SendMessage,
169 Self::CreateChannel,
170 Self::DeleteChannel,
171 Self::ManageChannel,
172 Self::CreateRole,
173 Self::DeleteRole,
174 Self::ManageRole,
175 Self::CreateInvite,
176 Self::ManageInvite,
177 Self::ManageServer,
178 Self::ManageMember,
179 ];
180
181 all_perms
182 .into_iter()
183 .filter(|p| permissions & (*p as i64) != 0)
184 .collect()
185 }
186}